SlideShare a Scribd company logo
1 of 16
Download to read offline
此⽂文根据【QCON⾼高可⽤用架构群】分享内容,由群内【编辑组】志愿整理,转发请注明来⾃自“⾼高可⽤用架
构(ArchNotes)”微信公众号。
陈宗志:奇虎360基础架构组 ⾼高级存储研发⼯工程师,⺫⽬目前负责360分布式存储系统Bada的设
计和实现,同时负责360虚拟化相关技术的研究。
本次分享主题
主要向⼤大家介绍⼀一下360⾃自主研发的分布式存储系统Nosql-Bada,作为设计者我⼀一直觉得设计
过程就是在做⼀一些折衷,所以⼤大部分的内容是我们开发实现Bada过程中的⼀一些经验和坑, 也有
很多的权衡, 希望和⼤大家⼀一起分享, 有不对的地⽅方欢迎指出。
虽然项⺫⽬目⺫⽬目前还未开源, 但是我们的⼀一些组件, ⽤用于异步同步数据的Mario库等, 均已经开源,后
续Bada也会开源。这是360官⽅方的Github账号https://github.com/Qihoo360
主要应⽤用场景
我们的定位是海量数据的持久化存储, 为线上的热⻔门应⽤用服务。不过我们⺫⽬目前没有接⼊入跟钱相关
的业务, 因为我们的系统毕竟是最终⼀一致性的系统。
我们倾向使⽤用Bada的⽤用户数据value的⼤大⼩小在10k以内, 那么我们的延迟能够做到1ms左右。我们
为了读取性能有⼀一定的优势, ⼀一般要求机器都挂载SSD盘。如果⽤用于存储冷数据, 我们会建议⽤用
户存数据到公司的其他存储产品, ⽐比如hbase,cassandra等等。
⺫⽬目前公司内部云盘, 移动搜索, LBS, Onebox, 导航影视, ⽩白名单等多个业务均在使⽤用。
云盘的场景是:通过Bada查询⽂文件所在的存储位置。这个业务数据量千亿级别, 每天的访问量
近百亿
LBS这个业务是将所有的POI的信息存储在Bada中, 业务需要在5个机房进⾏行数据同步。每天的
请求量⼗十亿级别。
整体架构
Bada SDK 是我们提供给⽤用户SDK, 360 QConf 配置管理服务 ⼤大家之前也了解过, 我们是QConf
的重度⽤用户。⽤用户通过SDK从QConf中获得存活的Bada节点, 然后进⾏行访问。
Data Server是我们的服务节点,其设计是学习⾃自Amazon Dynamo(不过好像Dynamo 本⾝身也被
很多⼈人喷), 每⼀一个节点都是对等结构, 每⼀一个节点存储了所有的元信息。为什么这么做?
⺫⽬目前主流的设计⼀一般是两种:
BigTable 为代表的, 有MetaServer, DataServer的设计, MetaServer存储元数据信息,
DataServer存储实际的数据。包括 BigTable, HBase, 百度的Mola等等。
Dynamo 为代表的, 对等结构设计. 每⼀一个节点都是⼀一样的结构, 每⼀一个节点都保存了数据的
元信息以及数据. 包括 Cassandra, Riak 等等。
Bada 的选择
其实我觉得两个结构都是合适的。为了部署, 扩展等⽅方便,我们不希望部署的时候需要分开部署
Meta节点, Data节点。计算机⾏行业, 加⼀一层可以解决⼤大部分问题, 因此我们觉得对等⺴⽹网络的设计
更有挑战性。个⼈人观点, 在数据量更⼤大的情况下, Meta 节点极有可能成为瓶颈。当然Dynamo的
结构肯定也有⾃自⾝身的缺点, ⽐比如如何保证元数据的⼀一致性等问题。
Data Server主要模块
Network Proxy: ⽤用于接收客户端的请求, 我们的协议是定制的protobuf 协议, Network
Proxy模块负责解析协议, 然后请求转发到对应的节点
Meta Info: ⽤用于存储公共的元信息, 元信息包括每⼀一个分⽚片存储在哪个节点
DB Engine: 我们底下的引擎是基于LevelDB的定制化开发, 包括⽀支持cas, 过期时间, 多数
据结构等等
数据分布策略
可以看到我们⺫⽬目前使⽤用的是有主从的副本策略, 图中的Primary 是主节点, Secondary 是从节
点。为什么这么做?
⾸首先为什么不使⽤用ec编码(erasure code 纠删码), 因为ec编码主要⽤用于保存偏冷数据, ec编码
遇到的问题是如果某⼀一个副本挂掉以后, 想要恢复副本的过程必须与其他多个节点进⾏行通信来恢
复数据, 会照成⼤大量的⺴⽹网络开销. 因此这⾥里3副本更合适。
常⻅见的分布式系统的多副本策略主要分成两类:
以Cassandra, Dynamo 为主的, 没有主从结构的设计, 读写的时候满⾜足quorum W + R > N,
因此写⼊入的时候写⼊入2个副本成功才能返回。读的时候需要读副本然后返回最新的。这⾥里的
最新可以是时间戳或者逻辑时间。
以MongoDB, Bada为主的, 有主从结构的设计, 那么读写的时候, 客户端访问的都是主副本,
通过binlog/oplog 来将数据同步给从副本。
两种设计都只能满⾜足最终⼀一致性。那么我们再从CAP理论上看, 那么都是在哪些维度做了权衡?
从性能上来看,有主从的设计很明显性能会由于⽆无主从的, 因为有主从的设计只需要访问⼀一
个副本就可以返回, ⽽而⽆无主从的⾄至少两个副本返回才可以。
从⼀一致性来看,有主从的设计如果挂掉⼀一个节点, 如果这个节点是主, 那么就会造成由于数
据同步的不及时, 这段时间写⼊入的数据丢。如果挂掉的是从节点, 那么则对数据没有任何的
影响。只要这个节点在接下来的时间内能够起来即可。⽆无主从的设计如果挂掉⼀一个节点, 理
论上对结果是⽆无影响的, 因为返回的时候会⽐比较最新的结果。有主从的结构由于写⼊入都在⼀一
个节点, 因此不存在冲突。⽽而⽆无主从的结构由于写⼊入的是任意的两个副本, 会存在对同⼀一个
key的修改在不同的副本, 导致客户端读取的时候是两个不⼀一致的版本, 这个时候就需要去解
决冲突, 常⻅见的⽅方案就涉及到vector clock, 时间戳等等。不过, 总体来看⽆无主从的设计⼀一致
性应该优于有主从的设计。
从分区容错来看, 两边都必须有⼀一半以上的节点存活才能够对外提供服务, 因为有主从的设
计中必须获得超过⼀一半节点的投票才能成为主节点。⽽而⽆无主从的结构, 常⻅见在W = 2, R = 2
的情况下, 必须2个副本以上才能对外提供服务。
从可靠性来看,有主从的设计因为只访问⼀一个副本, 性能优于⽆无主从的设计。⽽而且⽆无主从的
设计中, 因为对单条数据必须有两次读取, 因此对系统的访问压⼒力也会⽐比⽆无主从的来的多。
当然有主从的设计容易造成主落在同⼀一个机器上, 造成负载不均的情况, 但是这⾥里只要将主
平均到所有的机器, 就可以解决这个问题。但是有主从的设计在切换主从的时候, 必然有⼀一
段时间⽆无法对外提供服务, ⽽而⽆无主从的设计则不存在这样的问题。总体来说, 笔者认为从可
靠性的⾓角度来说, 有主从的设计应该⽐比⽆无主从来的可靠。
我们使⽤用的是有主从结构的设计, 原因:
Bada主要的应⽤用场景对性能的要求⽐比较⾼高, ⼤大部分的请求需要在1ms左右的时间返回, 因此
有主从的设计, 性能更满⾜足需求
线上服务的可靠性是我们另外⼀一个考虑的因素
具体的分析过程可以看 http://baotiao.github.io/2015/03/Bada-design-replicaset/
数据分⽚片策略,我们叫两次映射.
key -> PartitionId(hash)
PartitionId -> Node(MetaData)
⽐比如上⾯面这张图中我们可以看出, 我们将所有数据分成10个Partition, 然后每⼀一个机器存有主节
点和从节点. 我们会尽可能的保证每⼀一个机器上⾯面的主节点是⼀一样多的, 这样能够做到每⼀一个节
点的负载都是均衡的。
请求流程
当请求的数据Primary正好是当前这个节点
当请求的数据Primary 不是当前节点
多机房架构
360的机房是⽐比较多的, ⽽而且某些机房之间的⺴⽹网络较差。业务部署⼀一个服务的时候, 后端的DB也
需要部署在多个机房上, 因此这个常常是业务的痛点。因此我们设计之初就考虑多机房的架构。
我们的多机房架构能保证
⽤用户不⽤用管理多个机房, 任意⼀一个机房数据写⼊入, 其他机房能够读取
在机房存在问题的时候, 我们可以⽴立刻切换机房的流量
提供每⼀一个机房之间数据的统计和Check
整体实现
这个是⺫⽬目前LBS业务的场景
可以看出我们这⾥里有⼀一个专⻔门的队列⽤用于同步机房之间的数据。这个QBus 是我们团队内部基于
kafka开发的消息队列服务。
⺫⽬目前主流的机房同步⽅方法也是两种:
节点负责机房数据的同步, ⽐比如Cassandra, CouchBase, Riak
由外部的队列来同步机房之间的数据, ⽐比如 Yahoo pnuts
Cassandra 做法
在写⼊入的时候, 每⼀一个机房的协调者。⽐比如这个图⾥里⾯面10这个节点。会把写⼊入发送给其它机房的
某⼀一个节点, 这个时候Client这边收到的只是根据配置的⼀一致性级别就可以返回, ⽐比如这⾥里配置的
只要1个返回即可, 那么Client写⼊入成功10这个节点以后,即可返回。⾄至于与其他机房同步是10这
个节点的事情, 这样⼦子客户端的写⼊入就可以在本地写⼊入, 不⽤用管多机房的latency。
这⾥里我们可以看到是Eventual Consistency. 那么Cassandra是如何做到冲突修复的呢. 这⾥里
Cassandra 读的时候有⼀一个Read Repair 机制, 就是读取的时候读取本地多个副本. 如果副本不
⼀一致, 那么就选时间戳最新的重新写⼊入. 让数据重新同步, 这⾥里Cassandra只是说修复本地多副本
数据不⼀一致的⽅方法, 同样的⽅方法我们也可以⽤用在多个IDC⾥里⾯面, 可以同时跑多个任务check不同机
房的数据, 然后修复他们.
CouchBase 做法
Continuous Replication. 提供配置的不同Server之间同步的Stream的个数, 也就是不同的机房之
间连接的数⺫⽬目是可配置的. 解决冲突办法. CouchBase提供的是最终⼀一致性的⽅方法. 不同的版本之
间⾸首先根据修改的次数, 然后是修改时间等信息.
我们最后考虑的是使⽤用团队内部的QBus作为我们通信的队列, 主要考虑
省去了⾃自⼰己实现队列的⿇麻烦
稳定运⾏行于线上, 有专⻔门的同事维护. 减少的很多问题
Bada ⺫⽬目前线上3种多机房的使⽤用场景
单机房写⼊入, 任意机房读取
跨机房写⼊入, 任意机房读取
任意机房写⼊入, 任意机房读取
我们的实现⽅方案也是通过QConf来实现。客户端访问的时候, 从QConf中读取⺫⽬目前需要访问的机
房, 默认是访问本机房, 如果需要跨机房访问, 将QConf中的配置制定成需要访问的机房就可以
了。
多机房写⼊入的冲突解决⽅方案
时间戳最新

任意机房写⼊入数据, 根据时间戳来进⾏行冲突解决。
Yahoo Pnuts Primary Key
这⾥里我们对每⼀一个Key 有⼀一个Primary IDC, 也就是这个Key的修改删除等操作都只会在当前这个
IDC完成, 然后读取可以有多个IDC去读取. 那么因为对于同⼀一个Key的修改, 我们都在同⼀一个IDC
上. 我们通过给每⼀一个Key加上⼀一个Version信息, 类似Memcached的cas操作, 那么我们就可以保
证做到⽀支持单条数据的事务。如果这条数据的Primary IDC是在本机房, 那么插⼊入操作很快。
如果这条数据的Primary IDC不是本机房, 那么就有⼀一个Cross IDC的修改操作, 延迟将会⽐比较
⾼高。不过我们考虑⼀一下我们⼤大部分的应⽤用场景,⽐比如微博, 90%的数据的修改应该会在同⼀一个机
房。⽐比如⼀一个⽤用户有⼀一个profile信息, 那么和修改这个信息的基本都是这个⽤用户本⼈人, 90%的情况
下应该就是在同⼀一个地点改, 当然写⼊入也会在同⼀一个机房. 所以⼤大部分的修改应该是同⼀一个机房
的修改。但是访问可能来⾃自各个地⽅方,当然为了做优化, 有些数据可能在⼀一个地⽅方修改过了以后,
多次在其他地⽅方修改, 那么我们就可以修改这个Key的Primary IDC到另外这个机房。
Vector Lock
Vector Lock的核⼼心思想就是Client对这个数据的了解是远远超过服务端的, 因为对于服务端⽽而⾔言,
这个Key 对应的Value 对于Server 端只是⼀一个字符串。⽽而Client端能够具体了解这个Value所代
表的含义, 对这个Value进⾏行解析。那么对于这个例⼦子,当这两个不⼀一样的Value写⼊入到两个副本
中的时候, Client进⾏行⼀一次读取操作读取了多个副本。
Client发现读到的两个副本的结果是有冲突的, 这⾥里我们假设原始的Key的Vector Lock信息是
[X:1], 那么第⼀一次修改就是[X:1,Y:1], 另⼀一个客户端是基于[X:1]的Vector Lock修改的, 所以它的
Vector Lock信息就应该是[X:1,Z:1]。这个时候我们只要检查这个Vector Lock信息就可以可以发
现他们冲突, 这个就是就交给客户端去处理这个冲突.并把结果重新Update即可。
我们线上⺫⽬目前⽀支持的是时间戳最新, 以及Primary Key的⽅方案. ⼤大部分使⽤用的是时间戳最新来进⾏行
冲突解决。
多数据结构⽀支持
我们开发了⼀一套基于leveldb的多数据结构的引擎。⺫⽬目前⽀支持 Hash, List, Set, Zset等结构。
主要是由于⽤用户习惯了Redis提供的多数据结构, 能够满⾜足⽤用于快速开发业务的过程, 因此我
们也提供了多数据结构的⽀支持。
为什么不使⽤用ZooKeeper
ZooKeeper 和 Mnesia 对⽐比, ZooKeeper 是⼀一个服务, ⽽而 Mnesia是⼀一个库, 因此如果使⽤用
ZooKeeper的话, 我们需要额外的维护⼀一套服务。⽽而 Mnesia可以直接集成在代码⾥里⾯面,使
⽤用更⽅方便。
Mnesia 和 Erlang 集成的更好,Mnesia本⾝身就是⽤用Erlang 来开发。
Bada 和 MongoDB对⽐比
360的MongoDB 之前也是我们团队在维护, 在使⽤用MongoDB的过程中, 我们也遇到⼀一些问
题, ⽐比如MongoDB 的扩容⾮非常不⽅方便, 扩容需要很⻓长的时间, 因为MongoDB 扩容的过程是
将⼀一条⼀一条的数据写⼊入的. 我们开发的时候考虑到这些问题, 因此Bada 使⽤用的是leveldb, 当
需要扩容的时候, 只要将某⼀一个分⽚片下⾯面的数据⽂文件拷⻉贝过去即可. 前提是初始化的时候分
⽚片设置的⾜足够⼤大, 我们现实默认的分⽚片是1024
MongoDB 的数据膨胀度⽐比较⼤大, 因为MongoDB 毕竟是⽂文档型数据库, 肯定会保持⼀一些冗余
信息. 我们底下使⽤用leveldb, leveldb 本⾝身的压缩功能基于snappy 压缩. 还是做的⽐比较好. 线
上实际的磁盘空间⼤大⼩小相对于MongoDB 4:1
Bada 和 Cassandra 对⽐比
Cassandra的定位和Bada是不⼀一样的, 我们⾯面向的是线上频繁访问的热数据, 因此我们偏向于存
储⼩小value数据, 热数据, 对latency 的要求会苛刻。
⽐比如在云盘的场景, 我们存储的就是⽂文件的索引信息, ⽽而Cassandra存储的是具体的Cassandra的
数据, 也因此我们线上部署Bada的机器是挂载SSD盘的。
Bada 和 Redis 对⽐比
Bada 的性能⽐比Redis 低, 但是⺫⽬目前redis cluster 还没发展完善. 我们公司的DBA也在跟进
Redis cluster之中. 所以当数据量⽐比较⼤大的时候, Redis可能就不适⽤用于这么⼤大量的数据存
储。
Bada 的多数据结构⽀支持不如Redis来得完善. 因此我们也在逐步的⽀支持Bada的多数据结
构。
Redis 毕竟是内存型的服务. 因此假如⽤用户是偏向于存储持久化数据, 可能Redis不太合适。
⼀一些⾮非技术的经验
技术是为业务服务, 包括我们Bada在公司内部推⼲⼴广的过程中也发现, 我们很多业务很头疼的问题
在于360的机房较多, 每⼀一个⼩小业务都需要维护在多个机房, 因此为了降低⽤用户的开发试错成本,
我们将能标准化的事情都做了。包括我们组的定位也是专注底层技术, 加速产品团队开发效率,
尽可能降低业务对服务端集群架构的关注。
Q&A
Q1:客户端访问Bada时,怎么确保数据的均衡?从qconf拿到的是⼀一个ip列表吧?
是的。从QConf 中获得是随机的⼀一个节点的ip,所以对每⼀一个节点的访问基本的均衡的。服务
端这边, 因为我们是有主从结构的。但是我们的主从是分⽚片级别的主从,这点和redis cluster 不
⼀一样。⽐比如 Redis cluster 有Master 节点, slave节点,⼀一般情况slave 节点不接受任何的线上访
问,但是从下⾯面的图中可以看到 Bada 每⼀一个节点都有主, 从分⽚片。 因为每⼀一个节点的访问基本
是均衡的。
Q2:我有⼀一个问题,对于kv存储,选择leveldb的动机是什么?其他leveldb分⽀支是否考虑过?
对于存储的考虑, 我们之前对 Rocksdb 和 leveldb 做过对⽐比.在数据量⼩小的情况下, leveldb 的性
能和 Rocksdb 性能差不多. 数据量⼤大的时候 Rocksdb 会有性能优势. 因为我们之前对leveldb 做
了修改. 所以后续我们会迁移过去。
这⾥里我们的读写都⾛走的是 Master 节点. 只有当主节点挂掉以后, 才会访问从节点。
这个截图是之前对 leveldb 和 rocksdb 在数据量⽐比较⼩小的情况下的对⽐比
Q3:能否说⼀一下扩容,新增节点,以及摘除失效节点的处理?
从上⾯面两张图中可以看出, 我们会将新增的节点中, 均衡的将新的主节点迁移的新节点上。⺫⽬目前
扩容的过程是这样 我们先把当前这个节点加⼊入到集群。然后通过 rebalance 来进⾏行平衡。我们
⼀一般预先分配1024 个分配。这个应该也是业内场景的做法, 之前对腾讯的CKV 也是这么做,
Riak 也是这么做。
Q4:迁移是直接对leveldb复制,延时会有多少,在迁移过程中的访问如何处理呢?
迁移是直接对 leveldb 的⽂文件进⾏行复制, 这个时候性能是取决于⺴⽹网络的开销。这也是我们⽐比
mongo扩容快的地⽅方, mongo 在扩容的时候需要将数据⼀一条⼀一条写。迁移之前, 我们会将当前这
个节点进⾏行切主操作, 就是将所有的主切⾛走。那么这个时候是不会影响线上访问,带来的最多的
影响就是这个节点的⺴⽹网络有额外的开销,但是这个节点不是⾯面向⽤用户的请求的,所以影响不
⼤大。
Q5 :主切⾛走也需要有⼀一个时间吧?这个时间段内,如果要访问原来主上的数据,怎么处理?
这⾥里是这样的⼀一个过程, 迁移的时候⽐比如A 节点。 那么A节点上有主分⽚片, 那么在迁移之前,我
们会先将A节点上的主让给其他节点。这⾥里就涉及到追Binlog 的问题,如果这个时候⽤用户有⼤大量
的数据写⼊入, 会导致Binlog ⼀一直追不⻬齐。确实会导致⽆无法迁移。
Q6:关于leveldb的迁移,能否详细介绍⼀一下?
leveldb 的迁移很简单,就是直接通过scp 就可以了。这个是leveldb 本⾝身的功能,就是通过scp
leveldb 对应的数据⽂文件就可以。其实我们在binlog 这块也做了挺多的事情, 不过太细了有机会
下次讲。使⽤用binlog 来同步的副本策略之中, 常⻅见的问题⽐比如,分布式系统中由于主从切换导致
的数据丢失,然后我们也开发了binlog merge 来减少这种问题带来的影响。
Q7:leveldb的部分数据在内存中,这个迁移的时候怎么解决的?
这个没有影响。因为leveldb 的memtable 的数据在磁盘上有对应的.log ⽂文件。leveldb 启动的时
候会默认读取.log⽂文件, 将⾥里⾯面的内容加载到内存中。
Q8 : 我还是没太明⽩白,扩容的时候,A节点切到其他节点,是把A的meta信息做切换,然后再
复制数据,最后再映射meta?
扩容的时候是这样⼀一个过程。先将新增的节点加⼊入到现有的集群,不过这个节点不负责任何的
分⽚片, 因此没有任何数据在这个节点上;然后我们迁移的过程是节点上的⼀一个个的分⽚片进⾏行迁
移。⽐比如A 这个节点有 10~20 这⼏几个分⽚片, 并且这个时候 10~20 这个分⽚片是主, 那么依次我们先
将A这个节点的10~20变成从, 这个时候需要修改meta信息。然后接下来是复制对应的数据⽂文件
到新节点, 复制结束以后, 修改10~20 这⼏几个分⽚片到新的主上.最后修改meta 信息 ,和⼤大部分系统
⽐比最⼤大的不同在于 Bada 的主从是分⽚片级别的主从, 不是节点级别的主从.这样任何操作造成的影
响都是⾮非常⼩小. 并且可以做到每个节点的负载尽可能的均衡。
Q9:mnisa⽤用来存储meta信息吗?
mnesia 对于我们的定位就类似于ZooKeeper。有两个⽤用途, ⼀一个是选主的过程提供⼀一个全局的
锁, ⼀一个是保存元信息。
为什么不使⽤用ZooKeeper
ZooKeeper 和 mnesia 对⽐比, ZooKeeper 是⼀一个服务, ⽽而mnesia是⼀一个库, 因此如果使⽤用
ZooKeeper的话, 我们需要额外的维护⼀一套服务. ⽽而mnesia可以直接集成在代码⾥里⾯面. 使⽤用
更⽅方便
mnesia 和 erlang 集成的更好. Mnesia本⾝身就是⽤用Erlang 来开发
Q10:meta信息是存储在单独的机器上,⽽而不是分布在存储节点上吗?
不是, 存储在每⼀一个节点上. 每⼀一个节点都部有mnesia
Q11:既然⽤用mnesia,那你前端机器连在⼀一个集群?规模多⼤大?
前端是按照业务划分的,最⼤大的有36个节点.
感谢⺩王杰的记录与整理,国忠和四正的校对,其他多位编辑组志愿者对本⽂文亦有贡献。更多关
于架构⽅方⾯面的内容,读者可以通过搜索“ArchNotes”或⻓长按下⾯面图⽚片,关注“⾼高可⽤用架构”公众
号,查看更多架构⽅方⾯面内容,获取通往架构师之路的宝贵经验。转载请注明来⾃自“⾼高可⽤用架构
(ArchNotes)”微信公众号。

More Related Content

Similar to qcon-bada

ASP.Net MVC2 简介
ASP.Net MVC2 简介ASP.Net MVC2 简介
ASP.Net MVC2 简介Allen Lsy
 
微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew WuAndrew Wu
 
Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2twMVC
 
twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC
 
支付宝CSS构架
支付宝CSS构架支付宝CSS构架
支付宝CSS构架Sofish Lin
 
Css schema by_sofish
Css schema by_sofishCss schema by_sofish
Css schema by_sofishWebrebuild
 
新浪云计算公开课第一期:Let’s run @ sae(丛磊)
新浪云计算公开课第一期:Let’s run @ sae(丛磊)新浪云计算公开课第一期:Let’s run @ sae(丛磊)
新浪云计算公开课第一期:Let’s run @ sae(丛磊)锐 张
 
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案ArBing Xie
 
css框架研究
css框架研究css框架研究
css框架研究chandleryu
 
4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdfssuserd6c7621
 
Web爬虫那点事
Web爬虫那点事Web爬虫那点事
Web爬虫那点事Yihua Huang
 
51 cto下载 51cto信息图:openshift vs cloudfoundry
51 cto下载 51cto信息图:openshift vs cloudfoundry51 cto下载 51cto信息图:openshift vs cloudfoundry
51 cto下载 51cto信息图:openshift vs cloudfoundryHong Cai
 
2015中国软件技术大会-开放云介绍
2015中国软件技术大会-开放云介绍2015中国软件技术大会-开放云介绍
2015中国软件技术大会-开放云介绍Li Jiansheng
 
Oracle 全方位云解决方案概要
Oracle 全方位云解决方案概要Oracle 全方位云解决方案概要
Oracle 全方位云解决方案概要Ethan M. Liu
 
Oracle saa s paas overview
Oracle saa s paas overviewOracle saa s paas overview
Oracle saa s paas overviewChris Lee
 
Oracle雲端服務介紹 taiwan
Oracle雲端服務介紹   taiwanOracle雲端服務介紹   taiwan
Oracle雲端服務介紹 taiwanChieh-An Yu
 
Ruby on rails部署
Ruby on rails部署Ruby on rails部署
Ruby on rails部署Deng Peng
 

Similar to qcon-bada (20)

ASP.Net MVC2 简介
ASP.Net MVC2 简介ASP.Net MVC2 简介
ASP.Net MVC2 简介
 
微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu
 
Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2Asp.net mvc 從無到有 -twMVC#2
Asp.net mvc 從無到有 -twMVC#2
 
twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有twMVC#02 | ASP.NET MVC 從無到有
twMVC#02 | ASP.NET MVC 從無到有
 
支付宝CSS构架
支付宝CSS构架支付宝CSS构架
支付宝CSS构架
 
Css schema by_sofish
Css schema by_sofishCss schema by_sofish
Css schema by_sofish
 
新浪云计算公开课第一期:Let’s run @ sae(丛磊)
新浪云计算公开课第一期:Let’s run @ sae(丛磊)新浪云计算公开课第一期:Let’s run @ sae(丛磊)
新浪云计算公开课第一期:Let’s run @ sae(丛磊)
 
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案
[圣思园][Java SE]Websphere.application.developer(wsad)使用外置win cvs解决方案
 
css框架研究
css框架研究css框架研究
css框架研究
 
4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf
 
Web爬虫那点事
Web爬虫那点事Web爬虫那点事
Web爬虫那点事
 
51 cto下载 51cto信息图:openshift vs cloudfoundry
51 cto下载 51cto信息图:openshift vs cloudfoundry51 cto下载 51cto信息图:openshift vs cloudfoundry
51 cto下载 51cto信息图:openshift vs cloudfoundry
 
2015中国软件技术大会-开放云介绍
2015中国软件技术大会-开放云介绍2015中国软件技术大会-开放云介绍
2015中国软件技术大会-开放云介绍
 
App house
App houseApp house
App house
 
Oracle 全方位云解决方案概要
Oracle 全方位云解决方案概要Oracle 全方位云解决方案概要
Oracle 全方位云解决方案概要
 
Html5
Html5Html5
Html5
 
Oracle saa s paas overview
Oracle saa s paas overviewOracle saa s paas overview
Oracle saa s paas overview
 
Oracle雲端服務介紹 taiwan
Oracle雲端服務介紹   taiwanOracle雲端服務介紹   taiwan
Oracle雲端服務介紹 taiwan
 
Node分享 展烨
Node分享 展烨Node分享 展烨
Node分享 展烨
 
Ruby on rails部署
Ruby on rails部署Ruby on rails部署
Ruby on rails部署
 

More from 宗志 陈

More from 宗志 陈 (12)

Polardb percona-19
Polardb percona-19Polardb percona-19
Polardb percona-19
 
Disk and page cache
Disk and page cacheDisk and page cache
Disk and page cache
 
bada-data-beautiful
bada-data-beautifulbada-data-beautiful
bada-data-beautiful
 
Pika
PikaPika
Pika
 
Mario
MarioMario
Mario
 
Paxos introduction
Paxos introductionPaxos introduction
Paxos introduction
 
Log experience
Log experienceLog experience
Log experience
 
two-phase commit
two-phase committwo-phase commit
two-phase commit
 
Leveldb background
Leveldb backgroundLeveldb background
Leveldb background
 
Level db
Level dbLevel db
Level db
 
Beanstalk
BeanstalkBeanstalk
Beanstalk
 
Czzawk
CzzawkCzzawk
Czzawk
 

qcon-bada

  • 1. 此⽂文根据【QCON⾼高可⽤用架构群】分享内容,由群内【编辑组】志愿整理,转发请注明来⾃自“⾼高可⽤用架 构(ArchNotes)”微信公众号。 陈宗志:奇虎360基础架构组 ⾼高级存储研发⼯工程师,⺫⽬目前负责360分布式存储系统Bada的设 计和实现,同时负责360虚拟化相关技术的研究。 本次分享主题 主要向⼤大家介绍⼀一下360⾃自主研发的分布式存储系统Nosql-Bada,作为设计者我⼀一直觉得设计 过程就是在做⼀一些折衷,所以⼤大部分的内容是我们开发实现Bada过程中的⼀一些经验和坑, 也有 很多的权衡, 希望和⼤大家⼀一起分享, 有不对的地⽅方欢迎指出。 虽然项⺫⽬目⺫⽬目前还未开源, 但是我们的⼀一些组件, ⽤用于异步同步数据的Mario库等, 均已经开源,后 续Bada也会开源。这是360官⽅方的Github账号https://github.com/Qihoo360 主要应⽤用场景 我们的定位是海量数据的持久化存储, 为线上的热⻔门应⽤用服务。不过我们⺫⽬目前没有接⼊入跟钱相关 的业务, 因为我们的系统毕竟是最终⼀一致性的系统。 我们倾向使⽤用Bada的⽤用户数据value的⼤大⼩小在10k以内, 那么我们的延迟能够做到1ms左右。我们 为了读取性能有⼀一定的优势, ⼀一般要求机器都挂载SSD盘。如果⽤用于存储冷数据, 我们会建议⽤用 户存数据到公司的其他存储产品, ⽐比如hbase,cassandra等等。 ⺫⽬目前公司内部云盘, 移动搜索, LBS, Onebox, 导航影视, ⽩白名单等多个业务均在使⽤用。 云盘的场景是:通过Bada查询⽂文件所在的存储位置。这个业务数据量千亿级别, 每天的访问量 近百亿
  • 2. LBS这个业务是将所有的POI的信息存储在Bada中, 业务需要在5个机房进⾏行数据同步。每天的 请求量⼗十亿级别。 整体架构 Bada SDK 是我们提供给⽤用户SDK, 360 QConf 配置管理服务 ⼤大家之前也了解过, 我们是QConf 的重度⽤用户。⽤用户通过SDK从QConf中获得存活的Bada节点, 然后进⾏行访问。 Data Server是我们的服务节点,其设计是学习⾃自Amazon Dynamo(不过好像Dynamo 本⾝身也被 很多⼈人喷), 每⼀一个节点都是对等结构, 每⼀一个节点存储了所有的元信息。为什么这么做? ⺫⽬目前主流的设计⼀一般是两种:
  • 3. BigTable 为代表的, 有MetaServer, DataServer的设计, MetaServer存储元数据信息, DataServer存储实际的数据。包括 BigTable, HBase, 百度的Mola等等。 Dynamo 为代表的, 对等结构设计. 每⼀一个节点都是⼀一样的结构, 每⼀一个节点都保存了数据的 元信息以及数据. 包括 Cassandra, Riak 等等。 Bada 的选择 其实我觉得两个结构都是合适的。为了部署, 扩展等⽅方便,我们不希望部署的时候需要分开部署 Meta节点, Data节点。计算机⾏行业, 加⼀一层可以解决⼤大部分问题, 因此我们觉得对等⺴⽹网络的设计 更有挑战性。个⼈人观点, 在数据量更⼤大的情况下, Meta 节点极有可能成为瓶颈。当然Dynamo的 结构肯定也有⾃自⾝身的缺点, ⽐比如如何保证元数据的⼀一致性等问题。 Data Server主要模块 Network Proxy: ⽤用于接收客户端的请求, 我们的协议是定制的protobuf 协议, Network Proxy模块负责解析协议, 然后请求转发到对应的节点 Meta Info: ⽤用于存储公共的元信息, 元信息包括每⼀一个分⽚片存储在哪个节点 DB Engine: 我们底下的引擎是基于LevelDB的定制化开发, 包括⽀支持cas, 过期时间, 多数 据结构等等 数据分布策略 可以看到我们⺫⽬目前使⽤用的是有主从的副本策略, 图中的Primary 是主节点, Secondary 是从节 点。为什么这么做?
  • 4. ⾸首先为什么不使⽤用ec编码(erasure code 纠删码), 因为ec编码主要⽤用于保存偏冷数据, ec编码 遇到的问题是如果某⼀一个副本挂掉以后, 想要恢复副本的过程必须与其他多个节点进⾏行通信来恢 复数据, 会照成⼤大量的⺴⽹网络开销. 因此这⾥里3副本更合适。 常⻅见的分布式系统的多副本策略主要分成两类: 以Cassandra, Dynamo 为主的, 没有主从结构的设计, 读写的时候满⾜足quorum W + R > N, 因此写⼊入的时候写⼊入2个副本成功才能返回。读的时候需要读副本然后返回最新的。这⾥里的 最新可以是时间戳或者逻辑时间。 以MongoDB, Bada为主的, 有主从结构的设计, 那么读写的时候, 客户端访问的都是主副本, 通过binlog/oplog 来将数据同步给从副本。 两种设计都只能满⾜足最终⼀一致性。那么我们再从CAP理论上看, 那么都是在哪些维度做了权衡? 从性能上来看,有主从的设计很明显性能会由于⽆无主从的, 因为有主从的设计只需要访问⼀一 个副本就可以返回, ⽽而⽆无主从的⾄至少两个副本返回才可以。 从⼀一致性来看,有主从的设计如果挂掉⼀一个节点, 如果这个节点是主, 那么就会造成由于数 据同步的不及时, 这段时间写⼊入的数据丢。如果挂掉的是从节点, 那么则对数据没有任何的 影响。只要这个节点在接下来的时间内能够起来即可。⽆无主从的设计如果挂掉⼀一个节点, 理 论上对结果是⽆无影响的, 因为返回的时候会⽐比较最新的结果。有主从的结构由于写⼊入都在⼀一 个节点, 因此不存在冲突。⽽而⽆无主从的结构由于写⼊入的是任意的两个副本, 会存在对同⼀一个 key的修改在不同的副本, 导致客户端读取的时候是两个不⼀一致的版本, 这个时候就需要去解 决冲突, 常⻅见的⽅方案就涉及到vector clock, 时间戳等等。不过, 总体来看⽆无主从的设计⼀一致 性应该优于有主从的设计。 从分区容错来看, 两边都必须有⼀一半以上的节点存活才能够对外提供服务, 因为有主从的设 计中必须获得超过⼀一半节点的投票才能成为主节点。⽽而⽆无主从的结构, 常⻅见在W = 2, R = 2 的情况下, 必须2个副本以上才能对外提供服务。 从可靠性来看,有主从的设计因为只访问⼀一个副本, 性能优于⽆无主从的设计。⽽而且⽆无主从的 设计中, 因为对单条数据必须有两次读取, 因此对系统的访问压⼒力也会⽐比⽆无主从的来的多。 当然有主从的设计容易造成主落在同⼀一个机器上, 造成负载不均的情况, 但是这⾥里只要将主 平均到所有的机器, 就可以解决这个问题。但是有主从的设计在切换主从的时候, 必然有⼀一 段时间⽆无法对外提供服务, ⽽而⽆无主从的设计则不存在这样的问题。总体来说, 笔者认为从可 靠性的⾓角度来说, 有主从的设计应该⽐比⽆无主从来的可靠。 我们使⽤用的是有主从结构的设计, 原因: Bada主要的应⽤用场景对性能的要求⽐比较⾼高, ⼤大部分的请求需要在1ms左右的时间返回, 因此 有主从的设计, 性能更满⾜足需求 线上服务的可靠性是我们另外⼀一个考虑的因素
  • 5. 具体的分析过程可以看 http://baotiao.github.io/2015/03/Bada-design-replicaset/ 数据分⽚片策略,我们叫两次映射. key -> PartitionId(hash) PartitionId -> Node(MetaData) ⽐比如上⾯面这张图中我们可以看出, 我们将所有数据分成10个Partition, 然后每⼀一个机器存有主节 点和从节点. 我们会尽可能的保证每⼀一个机器上⾯面的主节点是⼀一样多的, 这样能够做到每⼀一个节 点的负载都是均衡的。 请求流程 当请求的数据Primary正好是当前这个节点 当请求的数据Primary 不是当前节点
  • 6. 多机房架构 360的机房是⽐比较多的, ⽽而且某些机房之间的⺴⽹网络较差。业务部署⼀一个服务的时候, 后端的DB也 需要部署在多个机房上, 因此这个常常是业务的痛点。因此我们设计之初就考虑多机房的架构。 我们的多机房架构能保证 ⽤用户不⽤用管理多个机房, 任意⼀一个机房数据写⼊入, 其他机房能够读取 在机房存在问题的时候, 我们可以⽴立刻切换机房的流量 提供每⼀一个机房之间数据的统计和Check 整体实现 这个是⺫⽬目前LBS业务的场景
  • 7. 可以看出我们这⾥里有⼀一个专⻔门的队列⽤用于同步机房之间的数据。这个QBus 是我们团队内部基于 kafka开发的消息队列服务。 ⺫⽬目前主流的机房同步⽅方法也是两种: 节点负责机房数据的同步, ⽐比如Cassandra, CouchBase, Riak 由外部的队列来同步机房之间的数据, ⽐比如 Yahoo pnuts Cassandra 做法 在写⼊入的时候, 每⼀一个机房的协调者。⽐比如这个图⾥里⾯面10这个节点。会把写⼊入发送给其它机房的 某⼀一个节点, 这个时候Client这边收到的只是根据配置的⼀一致性级别就可以返回, ⽐比如这⾥里配置的 只要1个返回即可, 那么Client写⼊入成功10这个节点以后,即可返回。⾄至于与其他机房同步是10这 个节点的事情, 这样⼦子客户端的写⼊入就可以在本地写⼊入, 不⽤用管多机房的latency。
  • 8. 这⾥里我们可以看到是Eventual Consistency. 那么Cassandra是如何做到冲突修复的呢. 这⾥里 Cassandra 读的时候有⼀一个Read Repair 机制, 就是读取的时候读取本地多个副本. 如果副本不 ⼀一致, 那么就选时间戳最新的重新写⼊入. 让数据重新同步, 这⾥里Cassandra只是说修复本地多副本 数据不⼀一致的⽅方法, 同样的⽅方法我们也可以⽤用在多个IDC⾥里⾯面, 可以同时跑多个任务check不同机 房的数据, 然后修复他们. CouchBase 做法 Continuous Replication. 提供配置的不同Server之间同步的Stream的个数, 也就是不同的机房之 间连接的数⺫⽬目是可配置的. 解决冲突办法. CouchBase提供的是最终⼀一致性的⽅方法. 不同的版本之 间⾸首先根据修改的次数, 然后是修改时间等信息. 我们最后考虑的是使⽤用团队内部的QBus作为我们通信的队列, 主要考虑 省去了⾃自⼰己实现队列的⿇麻烦 稳定运⾏行于线上, 有专⻔门的同事维护. 减少的很多问题 Bada ⺫⽬目前线上3种多机房的使⽤用场景 单机房写⼊入, 任意机房读取 跨机房写⼊入, 任意机房读取 任意机房写⼊入, 任意机房读取 我们的实现⽅方案也是通过QConf来实现。客户端访问的时候, 从QConf中读取⺫⽬目前需要访问的机 房, 默认是访问本机房, 如果需要跨机房访问, 将QConf中的配置制定成需要访问的机房就可以 了。 多机房写⼊入的冲突解决⽅方案 时间戳最新 
任意机房写⼊入数据, 根据时间戳来进⾏行冲突解决。
  • 9. Yahoo Pnuts Primary Key 这⾥里我们对每⼀一个Key 有⼀一个Primary IDC, 也就是这个Key的修改删除等操作都只会在当前这个 IDC完成, 然后读取可以有多个IDC去读取. 那么因为对于同⼀一个Key的修改, 我们都在同⼀一个IDC 上. 我们通过给每⼀一个Key加上⼀一个Version信息, 类似Memcached的cas操作, 那么我们就可以保 证做到⽀支持单条数据的事务。如果这条数据的Primary IDC是在本机房, 那么插⼊入操作很快。 如果这条数据的Primary IDC不是本机房, 那么就有⼀一个Cross IDC的修改操作, 延迟将会⽐比较 ⾼高。不过我们考虑⼀一下我们⼤大部分的应⽤用场景,⽐比如微博, 90%的数据的修改应该会在同⼀一个机 房。⽐比如⼀一个⽤用户有⼀一个profile信息, 那么和修改这个信息的基本都是这个⽤用户本⼈人, 90%的情况 下应该就是在同⼀一个地点改, 当然写⼊入也会在同⼀一个机房. 所以⼤大部分的修改应该是同⼀一个机房 的修改。但是访问可能来⾃自各个地⽅方,当然为了做优化, 有些数据可能在⼀一个地⽅方修改过了以后, 多次在其他地⽅方修改, 那么我们就可以修改这个Key的Primary IDC到另外这个机房。 Vector Lock Vector Lock的核⼼心思想就是Client对这个数据的了解是远远超过服务端的, 因为对于服务端⽽而⾔言, 这个Key 对应的Value 对于Server 端只是⼀一个字符串。⽽而Client端能够具体了解这个Value所代 表的含义, 对这个Value进⾏行解析。那么对于这个例⼦子,当这两个不⼀一样的Value写⼊入到两个副本 中的时候, Client进⾏行⼀一次读取操作读取了多个副本。 Client发现读到的两个副本的结果是有冲突的, 这⾥里我们假设原始的Key的Vector Lock信息是 [X:1], 那么第⼀一次修改就是[X:1,Y:1], 另⼀一个客户端是基于[X:1]的Vector Lock修改的, 所以它的 Vector Lock信息就应该是[X:1,Z:1]。这个时候我们只要检查这个Vector Lock信息就可以可以发 现他们冲突, 这个就是就交给客户端去处理这个冲突.并把结果重新Update即可。 我们线上⺫⽬目前⽀支持的是时间戳最新, 以及Primary Key的⽅方案. ⼤大部分使⽤用的是时间戳最新来进⾏行 冲突解决。 多数据结构⽀支持 我们开发了⼀一套基于leveldb的多数据结构的引擎。⺫⽬目前⽀支持 Hash, List, Set, Zset等结构。 主要是由于⽤用户习惯了Redis提供的多数据结构, 能够满⾜足⽤用于快速开发业务的过程, 因此我 们也提供了多数据结构的⽀支持。 为什么不使⽤用ZooKeeper ZooKeeper 和 Mnesia 对⽐比, ZooKeeper 是⼀一个服务, ⽽而 Mnesia是⼀一个库, 因此如果使⽤用 ZooKeeper的话, 我们需要额外的维护⼀一套服务。⽽而 Mnesia可以直接集成在代码⾥里⾯面,使 ⽤用更⽅方便。 Mnesia 和 Erlang 集成的更好,Mnesia本⾝身就是⽤用Erlang 来开发。 Bada 和 MongoDB对⽐比
  • 10. 360的MongoDB 之前也是我们团队在维护, 在使⽤用MongoDB的过程中, 我们也遇到⼀一些问 题, ⽐比如MongoDB 的扩容⾮非常不⽅方便, 扩容需要很⻓长的时间, 因为MongoDB 扩容的过程是 将⼀一条⼀一条的数据写⼊入的. 我们开发的时候考虑到这些问题, 因此Bada 使⽤用的是leveldb, 当 需要扩容的时候, 只要将某⼀一个分⽚片下⾯面的数据⽂文件拷⻉贝过去即可. 前提是初始化的时候分 ⽚片设置的⾜足够⼤大, 我们现实默认的分⽚片是1024 MongoDB 的数据膨胀度⽐比较⼤大, 因为MongoDB 毕竟是⽂文档型数据库, 肯定会保持⼀一些冗余 信息. 我们底下使⽤用leveldb, leveldb 本⾝身的压缩功能基于snappy 压缩. 还是做的⽐比较好. 线 上实际的磁盘空间⼤大⼩小相对于MongoDB 4:1 Bada 和 Cassandra 对⽐比 Cassandra的定位和Bada是不⼀一样的, 我们⾯面向的是线上频繁访问的热数据, 因此我们偏向于存 储⼩小value数据, 热数据, 对latency 的要求会苛刻。 ⽐比如在云盘的场景, 我们存储的就是⽂文件的索引信息, ⽽而Cassandra存储的是具体的Cassandra的 数据, 也因此我们线上部署Bada的机器是挂载SSD盘的。 Bada 和 Redis 对⽐比 Bada 的性能⽐比Redis 低, 但是⺫⽬目前redis cluster 还没发展完善. 我们公司的DBA也在跟进 Redis cluster之中. 所以当数据量⽐比较⼤大的时候, Redis可能就不适⽤用于这么⼤大量的数据存 储。 Bada 的多数据结构⽀支持不如Redis来得完善. 因此我们也在逐步的⽀支持Bada的多数据结 构。 Redis 毕竟是内存型的服务. 因此假如⽤用户是偏向于存储持久化数据, 可能Redis不太合适。 ⼀一些⾮非技术的经验 技术是为业务服务, 包括我们Bada在公司内部推⼲⼴广的过程中也发现, 我们很多业务很头疼的问题 在于360的机房较多, 每⼀一个⼩小业务都需要维护在多个机房, 因此为了降低⽤用户的开发试错成本, 我们将能标准化的事情都做了。包括我们组的定位也是专注底层技术, 加速产品团队开发效率, 尽可能降低业务对服务端集群架构的关注。 Q&A Q1:客户端访问Bada时,怎么确保数据的均衡?从qconf拿到的是⼀一个ip列表吧? 是的。从QConf 中获得是随机的⼀一个节点的ip,所以对每⼀一个节点的访问基本的均衡的。服务 端这边, 因为我们是有主从结构的。但是我们的主从是分⽚片级别的主从,这点和redis cluster 不 ⼀一样。⽐比如 Redis cluster 有Master 节点, slave节点,⼀一般情况slave 节点不接受任何的线上访 问,但是从下⾯面的图中可以看到 Bada 每⼀一个节点都有主, 从分⽚片。 因为每⼀一个节点的访问基本 是均衡的。
  • 11. Q2:我有⼀一个问题,对于kv存储,选择leveldb的动机是什么?其他leveldb分⽀支是否考虑过? 对于存储的考虑, 我们之前对 Rocksdb 和 leveldb 做过对⽐比.在数据量⼩小的情况下, leveldb 的性 能和 Rocksdb 性能差不多. 数据量⼤大的时候 Rocksdb 会有性能优势. 因为我们之前对leveldb 做 了修改. 所以后续我们会迁移过去。 这⾥里我们的读写都⾛走的是 Master 节点. 只有当主节点挂掉以后, 才会访问从节点。
  • 12. 这个截图是之前对 leveldb 和 rocksdb 在数据量⽐比较⼩小的情况下的对⽐比 Q3:能否说⼀一下扩容,新增节点,以及摘除失效节点的处理?
  • 13.
  • 14. 从上⾯面两张图中可以看出, 我们会将新增的节点中, 均衡的将新的主节点迁移的新节点上。⺫⽬目前 扩容的过程是这样 我们先把当前这个节点加⼊入到集群。然后通过 rebalance 来进⾏行平衡。我们 ⼀一般预先分配1024 个分配。这个应该也是业内场景的做法, 之前对腾讯的CKV 也是这么做, Riak 也是这么做。 Q4:迁移是直接对leveldb复制,延时会有多少,在迁移过程中的访问如何处理呢? 迁移是直接对 leveldb 的⽂文件进⾏行复制, 这个时候性能是取决于⺴⽹网络的开销。这也是我们⽐比 mongo扩容快的地⽅方, mongo 在扩容的时候需要将数据⼀一条⼀一条写。迁移之前, 我们会将当前这 个节点进⾏行切主操作, 就是将所有的主切⾛走。那么这个时候是不会影响线上访问,带来的最多的 影响就是这个节点的⺴⽹网络有额外的开销,但是这个节点不是⾯面向⽤用户的请求的,所以影响不 ⼤大。 Q5 :主切⾛走也需要有⼀一个时间吧?这个时间段内,如果要访问原来主上的数据,怎么处理? 这⾥里是这样的⼀一个过程, 迁移的时候⽐比如A 节点。 那么A节点上有主分⽚片, 那么在迁移之前,我 们会先将A节点上的主让给其他节点。这⾥里就涉及到追Binlog 的问题,如果这个时候⽤用户有⼤大量 的数据写⼊入, 会导致Binlog ⼀一直追不⻬齐。确实会导致⽆无法迁移。 Q6:关于leveldb的迁移,能否详细介绍⼀一下?
  • 15. leveldb 的迁移很简单,就是直接通过scp 就可以了。这个是leveldb 本⾝身的功能,就是通过scp leveldb 对应的数据⽂文件就可以。其实我们在binlog 这块也做了挺多的事情, 不过太细了有机会 下次讲。使⽤用binlog 来同步的副本策略之中, 常⻅见的问题⽐比如,分布式系统中由于主从切换导致 的数据丢失,然后我们也开发了binlog merge 来减少这种问题带来的影响。 Q7:leveldb的部分数据在内存中,这个迁移的时候怎么解决的? 这个没有影响。因为leveldb 的memtable 的数据在磁盘上有对应的.log ⽂文件。leveldb 启动的时 候会默认读取.log⽂文件, 将⾥里⾯面的内容加载到内存中。 Q8 : 我还是没太明⽩白,扩容的时候,A节点切到其他节点,是把A的meta信息做切换,然后再 复制数据,最后再映射meta? 扩容的时候是这样⼀一个过程。先将新增的节点加⼊入到现有的集群,不过这个节点不负责任何的 分⽚片, 因此没有任何数据在这个节点上;然后我们迁移的过程是节点上的⼀一个个的分⽚片进⾏行迁 移。⽐比如A 这个节点有 10~20 这⼏几个分⽚片, 并且这个时候 10~20 这个分⽚片是主, 那么依次我们先 将A这个节点的10~20变成从, 这个时候需要修改meta信息。然后接下来是复制对应的数据⽂文件 到新节点, 复制结束以后, 修改10~20 这⼏几个分⽚片到新的主上.最后修改meta 信息 ,和⼤大部分系统 ⽐比最⼤大的不同在于 Bada 的主从是分⽚片级别的主从, 不是节点级别的主从.这样任何操作造成的影 响都是⾮非常⼩小. 并且可以做到每个节点的负载尽可能的均衡。 Q9:mnisa⽤用来存储meta信息吗? mnesia 对于我们的定位就类似于ZooKeeper。有两个⽤用途, ⼀一个是选主的过程提供⼀一个全局的 锁, ⼀一个是保存元信息。 为什么不使⽤用ZooKeeper ZooKeeper 和 mnesia 对⽐比, ZooKeeper 是⼀一个服务, ⽽而mnesia是⼀一个库, 因此如果使⽤用 ZooKeeper的话, 我们需要额外的维护⼀一套服务. ⽽而mnesia可以直接集成在代码⾥里⾯面. 使⽤用 更⽅方便 mnesia 和 erlang 集成的更好. Mnesia本⾝身就是⽤用Erlang 来开发 Q10:meta信息是存储在单独的机器上,⽽而不是分布在存储节点上吗? 不是, 存储在每⼀一个节点上. 每⼀一个节点都部有mnesia Q11:既然⽤用mnesia,那你前端机器连在⼀一个集群?规模多⼤大? 前端是按照业务划分的,最⼤大的有36个节点. 感谢⺩王杰的记录与整理,国忠和四正的校对,其他多位编辑组志愿者对本⽂文亦有贡献。更多关 于架构⽅方⾯面的内容,读者可以通过搜索“ArchNotes”或⻓长按下⾯面图⽚片,关注“⾼高可⽤用架构”公众 号,查看更多架构⽅方⾯面内容,获取通往架构师之路的宝贵经验。转载请注明来⾃自“⾼高可⽤用架构