首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

【MaxCompute学习】隐式转化的问题

有一次计算一个数据的百分比,想把小数结果取2位,并拼接一个百分号展示在结果报表中。用到的sql如下 selectconcat(round(10230/1497409,4)*100,'%')fromdual; 很奇怪局部数据并没有保留2位小数,比如上面的数据返回的是67.99999999999999 我计算了下上面的结果大概得到的数据为0.0068 selectconcat(round(0.0066,4)*100,'%')fromdual;--0.66% selectconcat(round(0.0067,4)*100,'%')fromdual;--0.67% selectconcat(round(0.0068,4)*100,'%')fromdual;--0.6799999999999999% sele

优秀的个人博客,低调大师

hbase 学习(十六)系统架构图

HBase 系统架构图 组成部件说明 Client: 使用HBase RPC机制与HMaster和HRegionServer进行通信 Client与HMaster进行通信进行管理类操作 Client与HRegionServer进行数据读写类操作 Zookeeper: Zookeeper Quorum存储-ROOT-表地址、HMaster地址 HRegionServer把自己以Ephedral方式注册到Zookeeper中,HMaster随时感知各个HRegionServer的健康状况 Zookeeper避免HMaster单点问题 HMaster: HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master在运行 主要负责Table和Region的管理工作: 1 管理用户对表的增删改查操作 2 管理HRegionServer的负载均衡,调整Region分布 3 Region Split后,负责新Region的分布 4 在HRegionServer停机后,负责失效HRegionServer上Region迁移 HRegionServer: HBase中最核心的模块,主要负责响应用户I/O请求,向HDFS文件系统中读写数据 HRegionServer管理一些列HRegion对象; 每个HRegion对应Table中一个Region,HRegion由多个HStore组成; 每个HStore对应Table中一个Column Family的存储; Column Family就是一个集中的存储单元,故将具有相同IO特性的Column放在一个Column Family会更高效 HStore: HBase存储的核心。由MemStore和StoreFile组成。 MemStore是Sorted Memory Buffer。用户写入数据的流程: Client写入 -> 存入MemStore,一直到MemStore满 -> Flush成一个StoreFile,直至增长到一定阈值 -> 触发Compact合并操作 -> 多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除 -> 当StoreFiles Compact后,逐步形成越来越大的StoreFile -> 单个StoreFile大小超过一定阈值后,触发Split操作,把当前Region Split成2个Region,Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到2个Region上。 由此过程可知,HBase只是增加数据,有所得更新和删除操作,都是在Compact阶段做的,所以,用户写操作只需要进入到内存即可立即返回,从而保证I/O高性能。 HLog 引入HLog原因: 在分布式系统环境中,无法避免系统出错或者宕机,一旦HRegionServer意外退出,MemStore中的内存数据就会丢失,引入HLog就是防止这种情况 工作机制: 每个HRegionServer中都会有一个HLog对象,HLog是一个实现Write Ahead Log的类,每次用户操作写入Memstore的同时,也会写一份数据到HLog文件,HLog文件定期会滚动出新,并删除旧的文件(已持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知,HMaster首先处理遗留的HLog文件,将不同region的log数据拆分,分别放到相应region目录下,然后再将失效的region重新分配,领取到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。 HBase存储格式 HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,格式主要有两种: 1 HFile HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile 2 HLog File,HBase中WAL(Write Ahead Log) 的存储格式,物理上是Hadoop的Sequence File HFile 图片解释: HFile文件不定长,长度固定的块只有两个:Trailer和FileInfo Trailer中指针指向其他数据块的起始点 File Info中记录了文件的一些Meta信息,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等 Data Index和Meta Index块记录了每个Data块和Meta块的起始点 Data Block是HBase I/O的基本单元,为了提高效率,HRegionServer中有基于LRU的Block Cache机制 每个Data块的大小可以在创建一个Table的时候通过参数指定,大号的Block有利于顺序Scan,小号Block利于随机查询 每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成, Magic内容就是一些随机数字,目的是防止数据损坏 HFile里面的每个KeyValue对就是一个简单的byte数组。这个byte数组里面包含了很多项,并且有固定的结构。 KeyLength和ValueLength:两个固定的长度,分别代表Key和Value的长度 Key部分:Row Length是固定长度的数值,表示RowKey的长度,Row 就是RowKey Column Family Length是固定长度的数值,表示Family的长度 接着就是Column Family,再接着是Qualifier,然后是两个固定长度的数值,表示Time Stamp和Key Type(Put/Delete) Value部分没有这么复杂的结构,就是纯粹的二进制数据 HLog File HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是“写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。 HLog Sequece File的Value是HBase的KeyValue对象,即对应HFile中的KeyValue 结束语:这篇文章是我专门在网上弄下来的,算是hbase部分的终极篇吧,我的服务端的源码系列也要基于这个顺序来开展。

优秀的个人博客,低调大师

hbase 学习(十三)集群间备份原理

集群建备份,它是master/slaves结构式的备份,由master推送,这样更容易跟踪现在备份到哪里了,况且region server是都有自己的WAL 和HLog日志,它就像mysql的主从备份结构一样,只有一个日志来跟踪。一个master集群可以向多个slave集群推送,收到推送的集群会覆盖它本地的edits日志。 这个备份操作是异步的,这意味着,有时候他们的连接可能是断开的,master的变化不会马上反应到slave当中。备份个格式在设计上是和mysql的statement-based replication是一样的,全部的WALEdits(多种来自Delete和Put的Cell单元)为了保持原子性,会一次性提交。 HLogs是region server备份的基础,当他们要进行备份时必须保存在hdfs上,每个region server从它需要的最老的日志开始进行备份,并且把当前的指针保存在zookeeper当中来简化错误恢复,这个位置对于每一个slave 集群是不同的,但是对于同一个队列的HLogs是相同的。 下面这个是设计的结构图: 下面我们了解一下master和一个slave节点的整个过程。 1)当客户端通过api发送Put、Delete或者ICV到region server,这些KeyValue被转换成WALEdit,这个过程会被replication检测到,每一个设置了replication的列族,会把scope添加到edit的日志,然后追加到WAL中,并被应用到MemStore中。 2)在另一个线程当中,edit被从log当中读取来,并且只有可以备份的KeyValues(列族为scoped为GLOBAL的,并且不是catalog,catalog指的是.META. 和 -ROOT-) 3-1)这个edit然后被打上master群集的UUID,当buffer写满的时候或者读完文件,buffer会发到slave集群的随机的一个region server同步的,收到他们的region server把edit分开,一个表一个buffer,当所有的edits被读完之后,每一个buffer会通过HTable来flush,edits里面的master集群的UUID被应用到了备份节点,以此可以进行循环备份。 4-1)回到master的region server上,当前WAL的位移offset已经被注册到了zookeeper上面。 3-2)这里面,如果slave的region server没有响应,master的region server会停止等待,并且重试,如果目标的region server还是不可用,它会重新选择别的slave的region server去发送那些buffer。 同时WALs会被回滚,并且保存一个队列在zookeeper当中,那些被region server存档的Logs会更新他们在复制线程中的内存中的queue的地址。 4-2)当目标集群可用了,master的region server会复制积压的日志。 下面是一些具体的操作: 假设zookeeper当中的节点是/hbase/replication ,它会有三个子节点。 /hbase/replication/state /hbase/replication/peers /hbase/replication/rs The State znode state节点是记录是否可以进行备份的,它里面记录这个一个boolean值,true或者false,它是由hbase.replication决定的,同事它会在ReplicationZookeeper当中缓存,它还会因为在shell中执行了stop_replication而改变。 /hbase/replication/state [VALUE: true] The Peers znode 这个节点下面记录着所有需要备份的集群和他们当前的备份状态,如下: /hbase/replication/peers /1 [Value: zk1.host.com,zk2.host.com,zk3.host.com:2181:/hbase] /2 [Value: zk5.host.com,zk6.host.com,zk7.host.com:2181:/hbase]peer的id是自己在add_peer时候,自己提供的,后面的value是slave集群所使用的zookeeper集群,最后是所在的znode的父节点。 在每一个peer节点的下面还有一个表示状态的节点: /hbase/replication/peers /1/peer-state [Value: ENABLED] /2/peer-state [Value: DISABLED] The RS znode rs的节点下面包括了复制的region server以及需求复制的HLog的队列,看图就知道啦! 第一层节点记录着region server的机器名,端口号以及start code。 /hbase/replication/rs /hostname.example.org,6020,1234 /hostname2.example.org,6020,2856 下一层是需求复制的HLog的队列: /hbase/replication/rs /hostname.example.org,6020,1234 /1 /2 队列里面需要复制的HLog,值是已经被复制的最新的位置position。 /hbase/replication/rs /hostname.example.org,6020,1234 /1 23522342.23422 [VALUE: 254] 12340993.22342 [VALUE: 0]过程是上述的过程,下面展开讲一下具体的细节。 1)选择哪个region server去复制 当master节点准备好备份之后,它首先要通过slave集群的zookeeper,然后查看他们的rs的节点下面有多少可用的rs,然后随机选择他们中的一部分,默认是10%,如果有150个机器的话,会选择15个机器去发送。这个时候是有一个watcher在监视着slave集群的rs下面的变化,如果节点发生了变化,它会通知master节点的region server重发。 2)错误恢复,直接来个实际的例子 一个有3个region server集群正在和一个peer id为2的集群进行备份,每个region server下面都有一个队列 队列中的每个znode都是hdfs上的真实的文件名,“地址,端口.时间戳”。 /hbase/replication/rs/ 1.1.1.1,60020,123456780/ 2/ 1.1.1.1,60020.1234 (Contains a position) 1.1.1.1,60020.1265 1.1.1.2,60020,123456790/ 2/ 1.1.1.2,60020.1214 (Contains a position) 1.1.1.2,60020.1248 1.1.1.2,60020.1312 1.1.1.3,60020, 123456630/ 2/ 1.1.1.3,60020.1280 (Contains a position) 现在让1.1.1.2的zookeeper丢失session,观察者会创建一个lock,这个时候1.1.1.3完成了,它会把1.1.1.2的给接手过来,在自己的znode下面创建一个新的znode,并且加上dead的server的名称,就像下面这样子,原来的1.1.1.2的下面多了一层lock,1.1.1.3下面多了一个,和它原始的状态也不一样,前面多了个2。 /hbase/replication/rs/ 1.1.1.1,60020,123456780/ 2/ 1.1.1.1,60020.1234 (Contains a position) 1.1.1.1,60020.1265 1.1.1.2,60020,123456790/ lock 2/ 1.1.1.2,60020.1214 (Contains a position) 1.1.1.2,60020.1248 1.1.1.2,60020.1312 1.1.1.3,60020,123456630/ 2/ 1.1.1.3,60020.1280 (Contains a position) 2-1.1.1.2,60020,123456790/ 1.1.1.2,60020.1214 (Contains a position) 1.1.1.2,60020.1248 1.1.1.2,60020.1312然后1.1.1.3又自己倒腾了一会儿,假设它也挂了,最后的形态会是这样 1.1.1.1把1.1.1.3的未完成事业给接过了过来,所以我们看到1.1.1.1下面有个三手货和几个二手货。。。 /hbase/replication/rs/ 1.1.1.1,60020,123456780/ 2/ 1.1.1.1,60020.1378 (Contains a position) 2-1.1.1.3,60020,123456630/ 1.1.1.3,60020.1325 (Contains a position) 1.1.1.3,60020.1401 2-1.1.1.2,60020,123456790-1.1.1.3,60020,123456630/ 1.1.1.2,60020.1312 (Contains a position) 1.1.1.3,60020,123456630/ lock 2/ 1.1.1.3,60020.1325 (Contains a position) 1.1.1.3,60020.1401 2-1.1.1.2,60020,123456790/ 1.1.1.2,60020.1312 (Contains a position)原理说完了,从下面说说进行这个备份操作是哪些要求吧 (1)hbase的大的版本要一致 0.90.1 可以向0.90.0推送但是0.90.1不可以向0.89.20100725推送 (2)独立部署的zookeeper集群 (3)集群间的备份的表名和列族都要一致 (4)多个slave集群的话,要0.92以上版本 (5)集群间可以互相访问 (6)集群间的zookeeper.znode.parent不能相同 要使用这个集群建备份的功能需要先进行以下的设置: 1、修改hbase-site.xml文件 <property> <name>hbase.replication</name> <value>true</value> </property> 2、add_peer 输入这个命令,查看它的具体用法,然后添加 3、修改表的REPLICATION_SCOPE disable 'your_table' alter 'your_table', {NAME => 'family_name', REPLICATION_SCOPE => '1'} enable 'your_table' 4、list_peers 查看一下状态 5、备份完成之后如何进行数据校验,VerifyReplication就是专门来处理这个校验的。我们需要提供peer的id还有表名,verifyrep是它的简称,要用hadoop jar来运行。 集群之间备份的网址,说明他们是怎么工作的: http://hbase.apache.org/replication.html

优秀的个人博客,低调大师

HBase学习总结(5):HBase表设计

一、如何开始模式设计 当我们说到模式(schema),要考虑以下内容: (1)这个表应该有多少个列族? (2)列族使用什么数据? (3)每个列族应该有多少列? (4)列名应该是什么?(尽管列名不必在建表时定义,但是读写数据时是需要知道的。) (5)单元存放什么数据? (6)每个单元存储多少个时间版本? (7)行键结构是什么?应该包括什么信息? 1.问题建模 一个特定列族的所有数据在HDFS上会有一个物理存储。这个物理存储可能由多个HFile组成,理想情况下可以通过合并得到一个HFile。一个列族的所有列在硬盘上存放在一起,使用这个特性可以把不同访问模式的列放在不同列族,以便隔离它们。这也是HBase被称为面向列族的存储(column-family-oriented store)的原因。 在模式设计流程中尽早定义访问模式,以便通过它们检验你的设计决定。 为了定义访问模式,第一步最好定义想使用表来回答什么问题。 2.需求定义:提前多做准备工作总是有好处的 列限定符可以按数据处理,就像值。这和关系型系统不同,关系型系统的列名是固定的并且需要在建表时预先定义。 HBase没有跨行事务的概念,要避开在客户端代码里需要事务逻辑的设计,因为这会让你不得不维护复杂的客户端。 3.均衡分布数据和负载的建模方法 HBase的运算速度涉及很多考量因素。具体包括: (1)表中KeyValue条目数量(包括put的结果和delete留下的墓碑标记)。 (2)HFile里数据块(HFile block)的数量。 (3)平均一个HFile里KeyValue条目的数量。 (4)每行里列的平均数量。 e代表任何指定时间在MemStore里的条目数量,因为MemStore是使用跳表(skip list)实现的,所以查找行的时间复杂度是O(log e)。 宽表(wide table)的一行包括很多列。高表(tall table)是一种新模式,HFile里的KeyValue对象存储列族名字,使用短的列族名字在减少硬盘和网络I/O方面很有帮助。 HBase语境中的热点指的是负载极度集中在一小部分region上。因为负载没有分散在整个集群上,这是不合理的。服务这些region的几台机器承担了绝大部分工作,将成为整体性能的瓶颈。 4.目标数据访问 HBase表里只有键(KeyValue对象的Key部分,包括行键、列限定符和时间戳)可以建立索引。访问一个特定行的唯一办法是通过行键。 在列限定符和时间戳上建立索引,可以让你在一行上不用扫描前面所有的列而直接跳到正确的列。 从表中获取数据有两种方式,即get和scan。如果需要一行,可以使用get调用,这种情况下必须提供行键;如果想执行一次扫描(scan),如果知道起始和停止键,可以选择使用它们来限制扫描器对象扫描的行数。 根据指定的键的某个部分,可以限制读取硬盘的数据量或者网络传输的数据量。指定行键则只返回需要的行,但是服务器返回整行给客户端。指定列族让你进一步限制读取行的什么部分,因为如果行键跨多个列族,可以只读取HFile的一个子集。进一步指定列限定符和时间戳,可以让你减少返回客户端的列数,因此节省了网络I/O。 把数据放入单元值和把它放入列限定符或行键将占用相同的存储空间,但是把数据从单元移到行键将可能得到更好的性能。 一些基础知识: (1) HBase表很灵活,可以用字符数组形式存储任何东西。 (2) 在同一列族里存储相似访问模式的所有数据。 (3) 索引建立在KeyValue对象的Key部分上,Key由行键、列限定符和时间戳按次序组成。 (4) 高表可能支持你把运算复杂度降到O(1),但是要在原子性上付出代价。 (5) 设计HBase模式时进行反规范化处理是一种可行的办法。 (6) 想想如何能够在单个API调用里而不是多个API调用里完成访问模式。HBase不支持跨行事务,要避免在客户端代码里维护这种复杂的逻辑。 (7) 散列支持定长键和更好的数据分布,但是失去了排序的好处。 (8) 列限定符可以用来存储数据,就像单元一样。 (9) 因为可以把数据放入列限定符,所以它的长度影响存储空间。当访问数据时,它也影响了硬盘和网络I/O的开销,所以尽量简练。 (10) 列族名字的长度影响了通过网络传回客户端的数据大小(在KeyValue对象里),所以尽量简练。 二、反规范化 规范化是关系型数据库世界的一种技术,其中每种重复信息都会放进一个自己的表。这有两个好处:当发生更新或删除时,不用担心更新指定数据所有副本的复杂性;通过保存单一副本而不是多个副本,减少了占用的存储空间。需要查询时,在SQL语句里使用JOIN子句重新联结这个数据。 反规范化是一个相反概念。数据是重复的,存在多个地方。因为你不再需要开销很大的JOIN子句,这使得查询数据变得更容易、更快。 从性能观点看,规范化为写做优化,而反规范化为读做优化。 三、相同表里的混杂数据 尽可能分离不同的访问模式。 四、行键设计原则 在设计HBase表时,行键是唯一重要的事情,应该基于预期的访问模式来为行键建模。 行键决定了访问HBase表时可以得到的性能。这个结论根植于两个事实:region基于行键为一个区间的行提供服务,并且负责区间内每一行;HFile在硬盘上存储有序的行。当region刷写留在内存里的行时生成了HFile。这些行已经排过序,也会有序地刷写到硬盘上。HBase表的有序特性和底层存储格式可以让你根据如何设计行键以及把什么放入列限定符来推理其性能表现。 关系型数据库可以在多个列上建立索引,但HBase只能在键上建立索引,访问数据的唯一办法是使用行键。如果不知道想访问的数据的行键,就必须扫描相当多的行。 五、I/O考虑 以下技巧针对访问模式对设计行键进行优化。 1.为写优化 应该如何把数据分散在多个region上呢? (1)散列 如果你愿意在行键里放弃时间戳信息,使用原始数据的散列值作为行键是一种可能的解决方案。 散列算法有一个非零碰撞概率。使用散列函数的方式也很重要。 (2)salting 在思考行键的构成时,salting是一种技巧。 2.为读优化 尽量把较少的HFile数据块读入内存,来获得要寻找的数据集。因为数据存储在一起,每次读取HFile数据块时可以比数据分散存储时得到更多的信息。 这里行键的结构对于读性能很重要。 3.基数和行键结构 有效的行键设计不仅要考虑把什么放入行键中,而且要考虑它们在行键里的位置。 信息在行键里的位置和选择放入什么信息同等重要。 六、从关系型到非关系型 从关系型数据库知识映射到HBase没有捷径,它们是不同的思考方式。 关系型数据库和HBase是不同的系统,它们拥有不同的设计特性,可以影响到应用系统的设计。 1.一些基本概念 关系型数据库建模包括3个主要概念: a.实体(entity)—映射到表(table)。 b.属性(attribute)—映射到列(column)。 c.联系(relationship)—映射到外键(foreign-key)。 (1)实体 在关系型数据库和HBase中,实体的容器(container)是表,表中每行代表实体的一个实例。用户表中每行代表一个用户。 (2)属性 为了把属性映射到HBase,必须区分至少两种属性类型: a.识别属性(identifying attribute):这种属性可以唯一地精确识别出实体的一个实例(也就是一行)。关系型表里,这种属性构成表的主键(primary key)。在HBase中,这种属性成为行键(rowkey)的一部分。 一个实体经常是由多个属性识别出来的,这一点正好映射到关系型数据库里的复合键(compound keys)概念。 b.非识别属性(non-identifying attribute):在HBase中,它们基本映射到列限定符。 (3)联系 逻辑关系模型使用两种主要联系:一对多和多对多。在关系型数据库中,把前者直接建模为外键(foreign key),把后者建模为连接表(junction table)。 HBase没有内建的联结(join)或约束(constrain),几乎不使用显示联系。 2.嵌套实体 HBase的列(也叫做列限定符)不需要在设计时预先定义。它们可以是任何东西。HBase具有在一个父实体或主实体的行里嵌套另一个实体的能力,但这远远不是一个灵活的模式行(flexible schema row)。 嵌套的实体是从关系型映射到非关系型的又一个工具。 如果你得到子实体的唯一方法是通过父实体,并且你希望在一个父实体的所有子实体上有事务级保护,这种技术是最正确的选择。 七、列族高级配置 1.可配置的数据块大小 HFile数据块大小可以在列族层次设置。数据块索引存储每个HFile数据块的起始键。数据块大小配置会影响数据块索引的大小。数据块越小,索引越大,因而占用的内存空间越大。同时,因为加载进内存的数据块更小,随机查找性能更好。 2.数据块缓存 把数据放进读缓存,但工作负载却经常不能从中获得性能提升。 3.激进缓存 可以选择一些列族,赋予它们在数据块缓存里有更高的优先级(LRU缓存)。 4.布隆过滤器 布隆过滤器允许对存储在每个数据块的数据做一个反向测试。当某行被请求时,先检查布隆过滤器,看看该行是否不在这个数据块中。 5.生存时间(TTL) HBase可以让你在数秒内在列族级设置一个TTL,早于指定TTL值的数据在下一次大合并时会被删除。如果你在同一单元上有多个时间版本,早于设定TTL的版本会被删除。 6.压缩 HFile可以被压缩并存放在HDFS上,HBase可以使用多种压缩编码,包括LZO、Snappy和GZIP。 注意,数据只在硬盘上是压缩的,在内存里或通过网络传输时是没有压缩的。 7.单元时间版本 在默认情况下,HBase每个单元维护3个时间版本,这个属性是可以设置的。 同时也可以指定列族存储的最少时间版本数。 八、过滤数据 过滤器也被称为下推判断器,支持你把数据过滤标准从客户端下推到服务器。 较为常用的过滤器包括: 1.行过滤器 这是一种预装的比较过滤器,支持基于行键过滤数据。 2.前缀过滤器 这是行过滤器的一种特例,它基于行键的前缀值进行过滤。 3.限定符过滤器 它是一种类似于行过滤器的比较过滤器,不同之处是它用来匹配列限定符而不是行键。它使用与行过滤器相同的比较运算符和比较器类型。 4.值过滤器 它提供了与行过滤器或限定符过滤器一样的功能,只是针对的是单元值。 5.时间戳过滤器 它允许针对返回给客户端的时间版本进行更细粒度的控制。 6.过滤器列表 组合使用多个过滤器经常是很有用的。 九、小结 模式设计的出发点是问题,而不是关系。 模式设计永远不会结束。 数据规模是第一本质性的因素。 每个维度都是一个提升性能的机会。 本人微信公众号:zhouzxi,请扫描以下二维码:

优秀的个人博客,低调大师

Riak学习(3):Riak对比HBase(转)

文章转自:http://blog.nosqlfan.com/html/4081.html 文章来自Riak官方wiki,是一篇Riak与HBase的对比文章。Riak官方的对比通常都做得很中肯,并不刻意偏向自家产品。本文也是一样。 对比的Riak版本是1.1.x,HBase是0.94.x。 大方面对比 Riak 与 HBase 都是基于Apache 2.0 licensed 发布 Riak 的实现是基于Amazon 的 Dynamo 论文,HBase 是基于 Google 的 BigTable Riak 主要用 Erlang 写成,包括一部分的C,而 HBase 是用 Java 写的。 功能性对比 功能点 Riak HBase 数据模型 Riak 通过bucket作为命名空间,存储 Key-Value 信息 Buckets, Keys, and Values HBase 按预先定义好的 column family 结构来存储数据(每一条数据有一个key以及若干个列属性值组成,每列的数据都有自己的版本信息)。HBase 中的数据是按列进行有序存储的(不像关系型数据库中按行存储)。 HBase Data Model Supported Data Types 存储引擎 Riak 采用模块化的思想,将存储层作为引擎挂到系统上。你可以根据自己的需要选择不同的存储引擎。 Riak 支持的存储引擎 你也可以甚至 Riak 的backend API实现你自己的存储引擎。 HBase 是存在于 HDFS之上的,其数据文件存在HDFS中。与BigTable 类似,数据存储分为内存中的MemStore 和落地存储的 StoreFiles。其数据文件称为HFile,基于BigTable 的SSTable。可以直接使用JVM的 文件系统IO操作来对数据文件进行操作。 HDFS Hadoop Uses HDFS 数据访问接口 除了直接使用 Erlang 之外,Riak 还提供了两种数据访问接口,REST方式和 Protocol Buffer : HTTP Protocol Buffers Riak 的客户端都是基于上面的API来实现,目前对主流的语言支持很好。 Client-Libraries Community Developed Libraries and Projects HBase 的操作主要通过在JVM中直接执行代码。HBase 也提供了外部数据访问方式,包括REST方式以及Thrift协议的访问。 Java Interface REST Thrift 数据操作方式 Riak中支持下面四种方式的操作 对主键进行直接操作(GET,PUT,DELETE,UPDATE) MapReduce 方式 Riak 还提供 Secondary Indexes Riak Search 插件 上面几种方式的对比文章 HBase 有两种方式的数据操作,通过对有序key值进行扫描查询,获取value值,或者借助强大的Hadoop来进行MapReduce查询 Scanning MapReduce Secondary Indexes 数据一致性问题 Riak 通过 vector clock的方式来维护数据版本,处理不一致的情况。同时你也可以不使用vector clock,而是采用基于时间戳的 “last-write-wins” 策略 Vector Clocks Why Vector Clocks Are Easy Why Vector Clocks Are Hard HBase 采用了强一致性的读写保证。数据会在多个不同的region中进行保存。Column families 可以包含无限多个数据版本,每个版本可以有自己的TTL Consistent Architecture Time to Live 并发 Riak 集群中的所有节点都能同时进行读写操作,Riak只负责进行数据的写入操作(基于vector clock进行带版本控制的保存),在数据读取的时候再来定义数据冲突的处理逻辑。 HBase 通过行级锁来保证写操作的原子性,但是不支持多行写操作的事务性。数据扫描操作不保证一致性。 Consistency Guarantees 复制 Riak 的数据复制系统的理论来源主要是Dynamo 的论文和 Eric Brewer 博士的CAP 理论。Riak 采用一致性hash对数据进行分片,同一份数据会在多个节点中保存备份。在一致性hash的理论支持下,Riak采用的是虚拟节点的方式来实现数据的复制并进行数据平衡分配的保证。引入虚拟节点使得数据与实际节点间能够保持松耦合 Replication Clustering Riak 的API 提供在一致性和可用性之间的自由选择,你可以根据自己的应用场景选择不同策略。在最初存储数据到Riak中时,可以按bucket为单位进行复制方式的配置。在后续的读写操作中,每次都能够再进行复制份数的设置。 Reading, Writing, and Updating Data HBase 是典型的最终一致性实现,数据复制通过 master向slave的推送来实现。最近HBase也添加了master-master 的实现。 Replication 扩展性 Riak 支持动态添加我删除节点,所有节点都对等,不存在主从的区别。当向Riak 中添加一个节点后,集群会通过gossiping 发现节点并分配对应的数据范围并进行数据迁移。移除节点的过程相反。Riak提供了一系列工具来完成节点的增删操作。 Adding and Removing Nodes Command Line Tools HBase 以regions为单位进行分片,region会分裂和合并,并自动在多个节点间分配。Regions Node Management HBase Architecture 多数据中心的数据同步 只有Riak的企业版才支持多数据中心的部署方案,通常用户仅支持单数据中心的部署。 Riak Enterprise HBase通过region来进行分片,天然就支持多数据中心的部署。 Node Management 图形化的监控管理工具 从Riak 1.1.x 开始,Riak 发布了 Riak Control,这是一个针对Riak的开源的图形化管理工具。 Riak Control Introducing Riak Control HBase 有一些开源社区开发的图形化工具,同时也有一个命令行的控制终端能用。 Admin Console Tools Eclipse Dev Plugin HBase Manager GUI Admin 来源:wiki.basho.com

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册