Lemcoden

来自于大数据攻城狮的分享

0%

前情提要

jvm的轻量级爽口讲解–内存管理子系统(俗称垃圾回收)〇贰

其中对象的引用链路描述有误,现已经更改(应该是查找根节点引用的对象,而不是查找引用根节点的对象)

前言

1
2
3
4
hey!guys,I'm back,关于之前两篇的blog,博主尽可能进行debug,毕竟一篇好的blog是需要经过不断修改打磨的,
就像我们敲过的代码,如果不去不断的重构,之后必将"积重难返",然后还有一个,关于图片显示的问题,这个博主也
正在全力解决当中,准备把图床转到国内(此行为需要备案),域名正在备案中.......请大家耐心等待。好了我们继续上一
篇的问题,上一篇我们留下一个关键的问题,如何进行垃圾内存的并发标记,这次,我们就从这个问题开始。

再聊并发可达性分析

上一篇关于并发可达性问题,我们只是简单的一笔带过,这次我们利用对象图,帮我们把问题描述的更加清晰一些,以便于更加清晰的理解和解决。首先我们先对对象在对象图中的颜色进行区分定义:

  • 白色:表示对象还没有被垃圾回收器访问过,也没有被标记过。
  • 黑色:表示对象已经被访问且标记为安全存活对象(即不是垃圾对象),不会再进行扫描。
  • 灰色:表示对象已经被访问,但是此对象所引用的其他对象至少有一个还没有被扫描过。只有灰色对象所引用的白色对象扫描完毕,其才能被标记为黑色对象,所以说在标记过程中, 黑色对象不能直接指向白色对象

好的,我们看一下标记过程的抽象图:
初始过程,黑色的方框对象为根节点,开始向下查找。

memory_sign1
中间标记过程,就像是波纹(dio:纳尼?)一样,以灰色对象为波峰持续推进

memory_sign2
最后直到所有的灰色对象都查找不到引用,将最后这批灰色对象标记为黑色。

memory_sign3
好了,正常的标记过程就是如此,但如果有用户线程来捣乱,那就不一样了

那用户线程如何捣乱呢?把正在查找的灰色对象对白色对象切断?我们先试一下,以下虚线为切断的引用

memory_sign4
好像结果并没有什么阻碍,最终查找的结果是正确的,因为用户已经切断了引用,而我们的标记结果也实时作出了改变。

那么添加黑色对象对已经查找的白色对象的引用呢?

memory_sign5
也同样的不会出现什么问题,最后的结果和原来一致,那么,如果两个同时叠加呢?

memory_sign6
唉?问题就出来了,如果我们切断灰色对象对白色对象的引用,然后用一个黑色对象引用此白色对象,会让这个白色对象到扫描的最后都不会标记为黑色,但他有黑色对象的引用,照这样的标记回收会使我们的回收掉本应该存活的对象。

现在,我们知道,要是并发收集出现错误,必须满足以下两个条件:

  • 切断从灰色对象到黑色对象的引用
  • 添加已经扫描过的黑色对象对白色对象的引用

只要我们破坏其中一个条件,并发标记便可以实现。

破坏第一个条件,当探测到切断灰色对象对白色对象的引用,把这个引用记录下来,然后再以记录过的灰色对象为根节点,再扫描一遍,这种方法叫做原始快照

破坏第二个条件,当添加黑色对象到白色对象的引用时,我们将这个黑色对象重置为灰色对象,再进行查找。这种方法叫做增量更新
CMS收集器是基于增量更新来做并发标记的,G1、shennandoah则是用原始快照来实现的,这些收集器,会在之后进行专门的一一讲解。

再聊谁实现

好了讲了这么多的理论,我们该讲讲实现了,其实还有一些理论还没有涉及,笔者会在下面以及后几篇补上,现在感觉理论比较枯燥,我们还是聊聊实际的吧。

接下来我们会聊到一些垃圾收集器,以及垃圾收集器所用到的之前的理论部分。

首先,我们先为垃圾收集器进行分类,Serial、ParNew,Parallel Scavenge,Serial Old,Parallel Old,CMS收集器,笔者称他们为经典的收集器,因为这些收集器都是专门管理新生代,或者老年代的。

而之后出现的G1,shennandoah,ZGC收集器,都是新生代,老年代并用的。

而 jdk11出现的Epsilon收集器比较特殊,它不做任何回收动作(我要你有何用?),至于其作用笔者会在之后描述。

目前我们只聊了聊经典收集器的理论,所以我们从经典的收集器开始聊起,

  • Serial 收集器(直译是电视连续剧?重在连续这个词)最早出现的垃圾回收器,它适用于单核的CPU,因此特别适合运行客户端方面的应用,虽然在之后的回收器层出不穷,但是在客户端应用方面,Serial收集器一直最低内存消耗发挥着作用。
  • ParNew 收集器,专管新生代的多线程收集器JDK1.3
  • Parallel Scavenge ParNew 收集器的进阶版一般Par开头的,都是多线程收集器,这款收集器主打可控的吞吐量,吞吐量?好像是一个新概念,没错,之前我们讲过,停顿时间是衡量垃圾回收性能的重要指标之一,另一个指标便是吞吐量,他是指用户运行时间在整个程序总运行时间(用户运行时间和垃圾回收时间)的占比。他有自己的参数JDK1.4
  • Serial Old 收集器 Serial收集器的老年代版本
  • Parallel Old 收集器专门管理老年代的收集器,在此收集器出现之前ParNew 收集器一直初一比较尴尬的境地,因为作为多线程的新生代收集器,他却只能与单线程的Serial 配合使用JDK6
  • CMS 划时代意义的收集器,我们之前所说的并发回收就是从这个收集器开始的,之前的所有收集器,都只能通过停顿其他用户线程进行标记和回收,但是他是老年代的收集器,其次,作为老年代的收集器,它却无法配合Parallel Scavenge使用。

以上就是对我们所讲的理论支撑的垃圾回收器的简单介绍,那我们怎么使用他们呢?
很简单,只要启动java的时候加入配置参数就好

1
java  -XX:+回收器参数   运行的Main类

那么下面给出的回收器参数

参数 描述
UseSerialGC 使用Serial + Serial Old 收集器
UseParNewGC 使用ParNew + Serial Old 收集器
UseConcMarkSweepGC 使用ParNew + CMS+Serial Old 的收集器组合进行回收 ,如果CMS收集器并发收集失败,会切换到Serial Old 收集器
UseParallelGC 使用Parallel Scavenge + Serial Old 收集器
UseParallelOldGC 使用 Parallel Scavenge + Parallel Old 收集器

这是我们目前可以通过参数切换到的收集器参数,我们会在下一篇blog,将参数写的更详尽一些,包括一些收集器的配置参数,和JDK9之后的从参数改变。

再聊一下停顿

我们前面聊了聊并发标记是如何实现的,现在我们聊一下如何让用户线程停顿,为什么要讲这个?因为可能会出现停顿时间异常的现象,如果我们不懂其中的原理将没有办法定位问题所在。

首先我们先退一步,上一篇博客,我们讲到GC ROOT 其中有很多类型的引用都会被作为GC ROOT,那么随着应用的体量的增大,引用数量必定猛增不减,这种时候我们如果在垃圾回收的时候,再去查询GC ROOT的引用,

那必然是不行的,因此,我们需要先整一个数据结构,在类型加载的时候,就把相关的引用写入数据结构中,这样我们不必在海量的引用中查找,只取数据结构里面的数据便可,JVM最经典的HotSpot虚拟机就是利用OopMap数据结构这样进行工作的

好了,GC Root的收集问题得到解决了,但是运行过程当中,引用关系肯定会改变,而JVM指令当中,大部分的指令都会造成引用关系的改变,我们不可能在每条指令后面都加一个OopMap结构,那对回收来说,空间成本将会变得额外的高昂。

因此,存储了OopMap数据结构外,在运行时,JVM会选择某些“特殊的位置”来记录引用信息,这些特殊的位置就叫做安全点,那么安全点应该如何设置呢?

安全点设置既不能太少而使回收程序等待时间过长,又不能太多增大程序运行负荷,因此安全点一般选在可长时间执行的地方,一般在方法调用、循环跳转、异常跳转等这些可以指令序列复用的地方。

简单总结一下问题

  • 如何做到并发可达性分析,方法分为哪几种?
  • 前期新生代,老年代分开管理的回收器都有那些?
  • 安全点是什么?一般在哪里设置

关于华夏世界各职称权限以及命令使用此处写一个简单的草稿

原因

主要是大家一直在问这个职业能干什么,服主不能一个权限教一个人,那样会累死的。。。。。所以写了这一篇简短的权限以及命令简介,注意:所有的命令都是通过聊天框输入生效

游客

游客基本只有登陆和注册的权限,进入地图后会被钉死在出生点,无法移动。
只能通过

1
/register 密码

注册,然后 通过

1
/login 密码

进行登陆

登陆后 会升级成为冒险者

冒险者

当你升级成为冒险者之后,你就默认获得了挖取破坏世界物块的权限,并且还有使用虫洞药水,通过物品召唤boss,召唤入侵等,你在个人模式都能正常使用的功能,冒险者并无特殊的命令可以使用。

建筑师

如果你开荒很多轮觉得无趣了,你可以向管理员或者超管申请成为建筑师,建筑师拥有生成任一物品和圈地(冻结部分物块)的权限,超管还赋予了建筑师一项紧急权限———-冻结全世界物块的权限,这样可以及时防止入侵者肆意破坏世界的建筑。不过一旦发现建筑师滥用权限开荒,管理员将进行删号处理(绝不顾惜)。

生成物品

生成物品及其简单,但是对管理来说特别危险,可以生成任意物品一旦流出,很容易破坏平衡。这就是管理为啥要删号的原因

1
/item 物品ID 物品数量

物品ID可以查泰拉瑞亚官方wiki,如果你英语比较好或者会使用chrome翻译的话,可以直接查Tshock官方的物品清单, 这里会列出所有版本出现的物品,没找到记得去旧版本卡看看。

圈地

圈地,即划定一个矩形的范围,在这个范围里,普通的冒险者是炸和挖不动物块的。然后有一个简单的问题,要确定一个矩形需要几个点?对,两个点,这个是数学问题,服主就不说明了。
所以圈地,就是我们用命令确定两个点,然后系统会自动圈地
首先确定第一个点,输入命令

1
/region set 1

输入命令后会出现

1
HIt a block to Set Ponit1

恩,翻译过来的意思就是 击打物块设置点1,注意是击打,对着空气乱挥是没有用的,击打的地方必须有物块,当你击打成功后会出现

1
set temp point 1

这个表示设置成功了,如果设置错了,就需要从/region set 1再开始
同理设置第二个点就用命令

1
/region set 2

下面怎么做不用我说吧,如果设置错了就再从/region set 2开始
然后两个点都设置成功后,可以通过

1
/region define 你设置的区域的名字

通过

1
/region list

列出所有圈地列表,如果有你圈的地的名字,就说明你设置成功了。
删除圈地可以用

1
/region delete 圈地名

来删除

世界物块冻结

如果某人恶意破坏世界物块,而你有没有圈住自己要保护的那一片地
可以通过

1
/antibuild

命令冻结世界物块,及时止损

管理员

管理员可是说是拥有最多权限的人了,除了上面的所有职业的权限外,管理员还有,设置用户组或者叫职称的权限,调整世界时间的权限,通过命令召唤boss的权限等等

服主目前只讲用户组的一般管理.

后期会进行更新,或者你可以通过Tshock官方文档了解权限和命令

首先介绍一下目前的用户组对应的职称名字

游客 => guest 冒险者 => default 建筑师 => builders 管理 => admin

如果你想更改用户的职称权限可以通过

1
/user group 用户名 用户组名字

修改职称

如果你想禁止掉某个用户可以通过

1
/ban add 用户名

禁止某用户

解禁用户可以通过

1
/ban del 用户名

删除用户命令是

1
/user del  用户名

修改世界时间的命令

1
/time 时间格式 HH:mm

好的职称协议目前就讲到这里

前情提要

jvm的轻量级爽口讲解–内存管理子系统(俗称垃圾回收)〇壹

上回,我们就jvm虚拟机内存的问题一路问下来,整出了整个jvm虚拟的知识点大纲。这次我们就问题树的最小子树,继续往下问,继续往下回答。就上次的某些问题问的有些突然,那些新概念像是不要钱的一样直接涌过来,让人有点懵,这次,笔者会尽可能的把它从哪里来,到哪里去,它的整个来龙去脉给它溜全了。

jvm内存为什么使用可达性分析算法而不是使用引用计数器算法实现内存块的标记

标记之后再回收?

关于整理的书籍,笔者有一本书推荐给大家,那就是 近藤麻理惠的《怦然心动的人生整理魔法》,近藤麻理惠是日本比较出名的整理大师,笔者最喜欢书中大师最核心的思想,也和我们这一章节要讲的东西很有关系,那就是要学会丢弃,一旦我们判定手中的东西,以后不再使用就可以丢弃他们。

作为面向对象的特性,我们甚至可以直接用现实中的整理,类比内存整理,就像那本书的核心思想一样,我们首先要确定内存是否是需要丢弃的垃圾内存,在垃圾回收器这里这个方法我们把它叫做标记算法,嗯对,先标记内存是否可用,再去回收,没毛病。

那么我们目前哪些内存标记算法呢?一共两种一种是引用计数器算法,一种是可达性分析算法。

引用计数器算法&可达性分析算法

引用计数器算法

他的实现很简单,就是给内存中存在的对象添加一个计数器,但它被引用时,它的计数器数值就加一,当它的引用数值变成0,就会被标记为垃圾对象,对其进行回收。

引用计数器算法,在垃圾回收领域应用很广泛,包括 Action Script3的FlashPlayer,Python语言以及游戏脚本领域得到许多应用的Squirrel都是使用引用计数器算法,但是在Java领域中却不是这样,我们主流的Java虚拟机(Hotspot,J9等)都没有选用引用计数器算法来标记内存,
主要原因是,这个看似实现简单的原理,却有很多意外情况需要处理,比如说比较突出的循环引用问题,

举个例子,我们新建两个实例A和B,

A实例里面的一个变量引用B,B实例的一个变量引用A,

然后我们把A,B实例置空,

如果我们的语言使用的引用计数器算法,那么我们的A,B变量将不会被回收,因为实例本身为空了,但是变量的引用还为1。

可达性分析算法

通过一系列称为“GC Roots”的根对象作为起始节点,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路程称为“引用链”。

感觉整个描述比较抽象,不过没关系,一般抽象的概念,在使用过程当中会变得具体,之后笔者会讲分代收集从某些方面是如何应用可达性分析算法,以及如何进行并发状态下的可达性收集,当讲到这一部分的时候,读者可以再会头看看这里。
(为了便于回头查找,笔者先把这行文字标识为粉色)
因为读者表述能力不足,下面这个关于GC Roots一般都包括哪些只能硬背了。

  • 在虚拟机栈中(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用方法堆栈中的参数、局部变量、临时变量等。
  • 在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。
  • 在方法区中常量引用的对象,譬如字符串常量池里的引用
  • 在本地方法栈帧中JNI(即通常所说的Native方法)引用的对象
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPonitExeception、OutofMemoryError)等,还有系统类加载器。
  • 所有被同步锁(synchronized 关键字)持有的对象
  • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等
    为了更形象的表示GC Root的标记过程笔者给出图片

gc_root

图片如上。我们通过GC Root节点往下查找他引用的节点,然后再继续查找引用的节点引用的节点禁止套娃,就这样将所有关于GC Root的引用链路查找完毕,最后将那些没有在引用链路中的节点标识为垃圾节点,进行回收

Stop the world?并行 and 并发?

既然可达性分析算法已经讲了,那我们顺便聊聊,标记算法的重点特性,我们知道在jvm虚拟机运行过程中的线程分为两大类,分别是 用户线程和垃圾回收线程

两个线程都会对我们上面的引用链路进行操作,那么问题就出来了,

如果垃圾回收线程在引用链路查找过程中,用户突然对查找过的引用进行变更操作,那么势必会使回收的变量产生问题,

所以,当垃圾回收线程在进行标记的过程中,会让用户线程进入短时间的停顿。这个现象被形象的称之为Stop the world。所以说Java程序运行过程中,如果使用内存量大的话,用户会感到有明显的


对,就是停顿,这是我们对GC回收优化的一个重要指标,如果你是Web端的服务程序,那么停顿时间这个指标是你的优化首选,毕竟没有哪个用户希望,在他使用服务的过程中经常出现明显的卡顿。

好的,讲到停顿,那么我们可不可以不进行停顿呢?答案是当然的,我们可以让用户线程和垃圾回收线程进行并发执行

什么?并发?对就是读者所理解的让回收线程和用户线程抢占CPU的时间片,但是这样子还会出现上面那种情况,用户修改标记过后的引用链路,导致回收了错误的对象或者叫变量。这个…………由于篇幅有限,这个问题的答案以及原理我们放到下一篇当中。(还有一个优化指标吞吐量和这个有关系)

回收算法&内存分代

既然我们聊完标记了,那么标记之后的回收我们也来聊一聊,应该怎么回收这些垃圾,对垃圾进行分类,哪种垃圾的用哪种算法回收效率最高。

关于标题的三个回收算法想必大家都已经很熟悉了,这里就简单用图提点一下概念。重点讲为什么?

回收-清除算法

回收算法中简单,最基础的算法,其实就是把标记过后的内存直接清除掉,这样的处理的有点是处理方式简单,回收效率高,但是正因为简单,没有考虑之后的内存插入,可能会导致后面,大对象的插入,会让计算机查找很长时间寻找连续的内存,具体怎么回收直接看下面的简图。
思维导图

标记-复制算法

为了标记清除算法的缺陷,基于标记-清除算法,又出现了标记-复制算法,简单来说,就是预留一半的内存区域,回收之后,将存活的内存对象紧密排列到预留的区域当中,这样当然可以回收过后得到规整的可用内存区域。但是缺点也很明显,我们需要两倍的内存空间来做,能不能减少预留的空间呢?当然可以,要解决这个问题,我们需要先回到GC的分代问题,为什么jvm内存要分年轻代,老年代?相信大家都知道,jvm堆内存主要分为年轻代,老年代,而年轻代,基本都是使用的标记-复制算法,所谓年轻代,就是内存区域中的大部分对象都是“朝生夕死”的。内存赋值之后,很快就会被标记为可回收,那么我们在年轻代进行回收的时候,就会回收到大量的垃圾对象,而余下存活的对象很少,这样我们就可以把标记-复制算法的预留区域设置的少一点,降低一点标记-复制算法所消耗的内存,在最常用的jvm Hotspot虚拟机当中,年轻代默认的主内存(eden区)和预留内存(suvivor1区和suvivor2区)的内存比例就达到了8:1:1的比例,也就是两个预留区总共占用百分之20的内存
思维导图

标记-整理算法

除了设置预留区域之外,我们还可以在内存回收之后进行内存的整理,这样我们也可以使用比较规整的内存区域,其抽象的过程就如下图,但是,如果我们内存回收之后,各个存活对象之间的空白区域很多,那么整理对于我们的回收线程是特别消耗时间和性能的事情,所以我们要找那种回收过程中要回收垃圾对象比较少的区域,这样回收之后,空白区域预留的比较少,可以消耗比较较少的计算资源进行整理,看到这里,你应该能反应到了吧,对就是老年代,这种回收方式对于老年代的内存是再合适不过了,因为老年代中的对象存活率比较高,产生的垃圾对象相对较少。
思维导图

好的,此篇博客基本就讲到这里,我把这此所讲述的问题列出来,当然有些问题仅仅是解决了一半而已,比如说,停顿具体是怎样实现的,并发标记是如何做的,还有一个没有列出来的,记忆集是怎么来的等等,这些问题笔者会在下一篇中写出答案,以下是我的问题列表:

  • 垃圾 标记算法有哪些,为什么使用可达性分析算法,而不是引用计数器算法?
  • jvm回收线程在标记过程中是否会造成停顿,为什么?
  • 垃圾回收算法有哪些,分别什么作用,他和内存分代有什么关系?

前言

昨天半夜啃书时,笔者突发奇想,要开一个新的系列主题,没错,如标题所言,关于jvm虚拟机的爽口简介,众所周知jvm虚拟机的底层知识相当枯燥,就像是发柴的鸡肉,即使嚼烂也难以下咽,究其原因,是看书的时候问题不明确,只能被博客文章,书中大量知识点牵着鼻子走,因此,笔者准备以问题驱动作为主线,我们先明确要问的问题,整理好问题之间的引用链路,然后再集中解答的方式,先给知识裹一层糖色(shai),让问题变得诱人,再去吃的话就没有那么柴了。那么废话不多说,本系列篇章开始(本篇博客所有问题将有蓝色字体标出,并在博客的最后重复给出,想挑战记忆力的小伙伴可以试着去解答)。

Read more »

前情提要:
hexo + github 搭建教程
记录一次github + hexo 文件的迁徙

前言

    填一下之前搭建博客的坑,之前发布了一篇搭建hexo的博客,有读者(无中生读者)反应,博客搭建完之后,网站访问很慢,的确,在这样的快节奏时代,超过5秒的网页大家都不想打开,所以笔者写了这篇关于博客的优化(感觉不能算作优化,只是填坑)。
Read more »

如果您觉得作者翻译的内容有帮助,让您学到了相关专业知识,请分享给更多人,让更多人学到大数据知识。您的分享,是作者翻译的动力!
![taking_the_work_out_of_networking]{cover_of_book}
人际交往更多的是长久的培养种植而不是即时的狩猎

--伊万·米斯纳

人际交是我们大多数人认为比较繁琐的多数事之一----它是一项需要从事的艰巨的任务,当我们需要一些东西:比如一份新工作,更好的事业指导,更优越的教育,或者其有用的信息时。 当我谈起发展这个想法的时候,几乎我提到的每个人都说同样的话:“我恨人际交往,任何可以帮助我逃避它,逃离它的东西都是极好的”,当我问起我在FaceBook或者Twitter的朋友什么东西是他们尤其仇恨的对于人际交往,他们的回复如下: “每个人都尝试他们自己做不到的事” “目标驱动的虚假性,对话是为了实现目标,而不是为了建立联系而感到假。” “我讨厌不得不和那些试图利用这段关系而可能忘记当前唯一共同目标的人进行表面的对话” 作为一生的性格内向者,强迫介绍和谈论太多关于我自己的事,甚至索要名片的想法一直令人厌恶,当我的日程上排满了会议,电话或者其他事务要求我说很多话,或者在拥挤的人群中,我会感到焦虑。 至今,尽管我自己需要自我保护和独处,但是在我六十七岁的最后已经在世界各地建立了上千的联系人。虽然我永远不会再房间里工作,但我不害怕和任何内向者开始一段对话。在我的长久而多样的职业生涯,我的人际关系每天都会使我的生活更加丰富,朋友和熟人(和他们所知道的人,等等等等)经常来找我,提供想法,支持,联系和介绍,并且我也这么做。 无论您属于内向型还是外向型,建立新连接的人际网络的需求已经不再重要,一些证明点如下: * 我们经常换工作,年轻的婴儿潮一代在他们的职业生涯中拥有十几份不同的工作,而千禧一代预计会拥有更多(美国劳工统计局) * 跳槽始于年轻,如今的大学毕业生在毕业后的头五年里,在公司工作的人数是早年的两倍(据领英统计) * 我们经常搬家,美国人一生中搬家的次数超过11次(FiveThirtEight.com) * 我们中大部分人为我们自己而工作,在21岁以上的美国人中,有将近4100万个体经营者,而且这一趋势还在增长。(MBO Pattern,Nation1099.com) 这些原因------工作的改变,自由职业化,地理迁徙-----它使我们大多数人都义不容辞地把建立人际关系网作为一种常规做法,在我们的职业生涯中,我们仍需要不断变化,并不断增长的各种各样的人来帮助我们。现代社会对“人际关系网”的定义是:努力与许多人见面、交谈,特别是为了获得对你有帮助的信息,听起来还不错,对吧? ***然而,人们讨厌这样做?*** 但是对于大多数人来说,社交网络让人联想到这样一幅画面:在你确保收集到的名片数量相等的情况下,把名片按在眼前的每个人身上.建立人际关系网的其他可怕的方面:为了得到一份新工作不得不去见陌生人;需要了解一个新地域新城市的内幕;试图利用招聘系统来匹配你的经验定位令人有趣的角色.这一切看起来都是虚假的,是赤裸裸的交易,另外,尽管我们花了很多时间避免社交,我们仍然认为必须在最需要社交的时候走出去。当事情看起来最糟糕的时候(即将到来的裁员,没有前途的角色,无法忍受的工作环境),我们会感到脆弱-----又是甚至是绝望。在这种情况下,谁会是最好的? 当然,也有人不相信他们需要社交,毕竟,他们说,他们的工作是安全的。(直到它不是),还有一些人觉得他们对目前的工作已经听天由命了,因为,坦率地说,他们想不出更好的东西了,或者因为各种各样的原因(终身职位,头衔降级,薪酬降低,通勤物流等等),他们觉得自己负担不起换工作。一个朋友向我描述了关于人际交往困惑他一生的难题:“传统上在社交场合中不允许讨论工作,不能妄尊自大,不能自我推销,不能投机取巧,不能利用朋友-----然后,作为专业的成人,必须以某种方式让自己融入市场上,这种冲突好像从来不会让人觉得不尴尬。” 对于内向的人来说,与陌生人交流的厌恶甚至恐惧会成倍增加。正如卡尔•荣格(Carl Jung)所描述的那样,内向的人需要独处的时间来充电,他们通过独处来恢复精力——而外向的人则通过与人交往而获得一种特殊的能量,他们似乎不需要休息。我们大多数人都在这两者之间。根据我自己的经验,以及我从同类的灵魂那里听到的,我们这些倾向于内向的人,比起我们在喋喋不休的人群中,更能自如地表达我们的思想。在谈话或嘈杂的房间里挤来挤去是最糟糕的琐事。在我重新回到这个世界之前,我需要一个计划外的时间来让我的大脑漫游并恢复活力。你也是吗? 2000年,硅谷经历了一次重大的经济衰退。那年,我加入了一家拥有18名员工的初创公司,这是一家早期的电子商务个人礼品商,名为Violet.com。经过了四个多月的动荡,我们彻底歇业了;没有新一轮的融资。我去了一家知名的代理机构,该机构正在旧金山开设办事处,结果时机不好(经济下滑导致引诱不到客户),不久公司就搬到洛杉矶的办公室-------其中不包括我。最后,我几乎没有什么工作可以从事,甚至于合同工作也很少。没有人在招聘。在接下来的15个月左右的时间里,我因工作或金钱不足而苦苦挣扎。我和我的同僚成立了一个非正式的支持小组,供几个朋友使用。我们每周见面,互相欢呼并分享线索。看看他们是否需要写作帮助。其中一个电话时打给我之前和我一起工作两次的朋友,他最近在一家名为Google的创业公司工作。我问她是否需要写作帮助;他告诉我他们只是聘请了一名市场营销作家,但打印让我牢记。 几个月后,她回了我电话。工作似乎堆积如山。我要进来见团队吗?她强调说,她不能直接雇佣我;其他人将不得不喜欢我的工作(和我)。我一定时风雨如磐的港口,因为在他们第一次见面的时,他们就要求我加入,我很热心几周之内,很明显,我影噶

为什么要使用Kylin

在使用一个框架之前我们都要问问自己为什么要使用这个框架,他要解决什么问题,这个框架在解决这方面问题有什么样的优势,Kylin也如此。
那么他是解决什么问题的呢?他是解决数据仓库工程的最后阶段,OLAP(联机分析处理)的查询慢的问题。
在实际的数据仓库项目中,我们需要在几亿甚至上百亿条的数据当中聚合查询我们所需要的信息,但是这对于批处理来说是非常缓慢的查询过程。但是kylin不同,它通过自己所独有的预计算功能,将原来查询所需的几个小时缩短为秒内返回。

使用kylin前的几个概念

维度:看待事物的角度,比如时间,地点,销售量,销售物品类别
度量:被聚合的统计值,也就是聚合运算的结果,它一般事连续的值。
Cube:数据魔方,我们传统的数据库的表字段在数据仓库的分析前,会先把字段转化为相应的维度和度量,维度和度量组成了整体的Cube
Cubeboid:我们通过维度和度量预先计算出所有查询的可能结果,每种可能结果的实体我们称之为Cuboid
星型模型:星型模型,雪花模型,事实星座模型主要是数据建模相关工作需要深度了解的知识,这里我简单举个例子,有兴趣的小伙伴可以自行查询。

kylin的工作过程

1.指定数据模型,定义维度和度量。(这个需要开发人员根据需求自己设置,博主会在后续的博客中说明)

2.预计算Cube,计算所有Cuboid并保存为物化视图。

这个我们举个例子,比如我们有一个电商的销售数据集,其中维度包括时间(Time),商品(Item),地点(Location)和供应商(Supplier),度量为销售额(GMV)那么所有的维度组合就有2^4=16种组合,其维度所构成的所有组合表如下
kylin_all_cuboid
上图每个原点代表一个cubiod,中括号的标识,表示这个cubiod所包含的查询维度
那么具体的内容是什么样的?
我们以Cuboid[Time,Location]为例,它所对应的SQL语句如下:
select Time,Location,Sum(GMV) as GMV from Sales group by Time, Location
根据以上SQL语句,我们不难想象出其查询的具体内容

3.执行查询时,读取Cuboid,运算,产生查询结果。

kylin的技术架构

和其他经典的大数据框架一样,我们先给出技术架构图
kylin技术架构
我们先看最左边,kylin以hive作为数据源,数据格式为星型模式的关系表形式(只支持星型模式,雪花模式可以自行转换),通过mapreduce作为计算框架来构建cube,构建完成后,保存cube的索引值到右侧的HBase当中,当用户有查询需求的时候,可以通过Kylin开放的RestApi,JDBC/ODBC接口。
PS:路由功能已弃用,数据源,构建引擎以及存储引擎可以替换,比如把hive替换为Kafka,Mapreduce替换为Spark,Hbase可以替换为Kudu等等。

Kylin的主要特点

SQL接口:对用户提供最简单的SQL接口,降低使用要求
支持超大数据集:理论上Kylin可以支撑的数据集大小没有上限,仅受限于存储系统的分布式计算系统的承载能力
压秒级查询:得益于Kylin的预计算,比如连接、聚合,在理想的预计算过程种就已经完成,这大大降低了查询实课所需要的计算量,提高了响应速度。
BI及可视化工具集成:ODBC接口,JDBC接口,Rest API,分析师可以沿用最熟悉的BI工具于Kylin一同工作。
查询速度:0(1)常数计划别的查询速度。也就是说查询速度并不是随数据量大小线性增长,而是不论数据量怎么增长,查询速度都不变。

起因

事情是这样子的,我很早之前注册的名为longzuzero的github账号,当时名字是随便想,用《龙族》小说名的汉语拼音加上英文的零,当时n年后,我准备开始写属于自己的技术博客时,才发现,这个名字没有任何意义,所以建立博客之初我把名字定义为
Lemcoden

Read more »

本篇博客分为三部分

  • github 账号注册,创建库,本地链接远程库
  • hexo 的安装,主题以及博文的部署
  • 域名的注册,设置转发
    Read more »