LightCloud的设计原理

LightCloud是最近看到的一个比较轻巧的分布式key-value数据库,尽管这类软件已经让人觉得审美疲劳,但我仍然觉得它的设计思路值得一提。

特色

除开其项目主页上列出来的特点不提,我觉得还能数得上的特色有:

    1. 理论上可以用任意key-value数据库做为底层存储,现在支持以tokyo tyrant或者redis作为底层的存储,如果使用redis可以获得更好的性能(大概提升30%~50%)
    2. 没有定制服务器端,基本上靠客户端语言来实现键值查找。优点是部署起来比较简单,缺点也是显而易见的,效率会有损失。
    3. 可以很方便的移植到其它语言上,我已经在github上找到一个ruby版本,甚至还有个php版本的实现。
    4. 可以方便的增加节点。
    5. 结构简单,方便hack

LightCloud的设计原理

Hash ring

LightCloud不能免俗的使用了一致性hash算法(Consistent Hashing),这是为了避免新增数据节点时发生集体拆迁事件。Consistent Hashing算法的原理请参考这里

last.fm的工作人员写的ketama算法算是比较常见的一致性算法,在libmemcached里大量使用。而LightCloud的作者当时还没发现合适的ketama python版,所以干脆自己捋起袖子写了个python版本的hash_ring,不到50行。这个是量身定制的,所以效率也还过得去,但是兼容ketama就别想了。

献上hash圈圈一个以明志:

LightCloud的hash环有什么与众不同?

其它分布式key-value数据库采用的办法是复制数据到多个节点上,例如Amazon Dynamo的复制策略图:

Dynamo用了许多办法解决consistent问题,系统相当复杂。而LightCloud直接使用tokyo tyrant的master-master复制功能,大幅简化了这部分的逻辑。所以在它的hash环上,单个节点其实是一对master-master的tokyo tyrant,焦不离孟不离焦。

在新增数据节点时,如果没有路由服务找到正确的服务器,可能会损失数据。那么LightCloud继续采用流氓手段解决这个问题,他又给上了个环,保证不会发生意外。这两个hash环里的节点仍然是之前提到的tokyo tyrant双人组,一个环叫lookup,记录了每一个key保存在哪个storage节点上;另外一个环叫storage,这是真正存放数据的地方。于是它的结构图变成了下面这个样子:

这部分比较难以理解,试着就上图阐述一下:

    1. 一个名叫A的家伙,住在storage_SB地区(storage ring)。同时,我们还告诉记性好的lookup_B(lookup ring),A君的地址为storage_SB。
    2. 很不幸或很幸运,咱们的数据膨胀到需要扩容了,于是新增了一个违章建筑storge_X,这个该死的建筑正好影响了我们找到A君。这时候,我们还可以问起记性好的lookup_B,A君住在哪个角落里啊? —— lookup_B日道:他就住在sotrage_SB一带~
    3. lookup这群家伙记性虽然好,但是也架不住人多,再也记不住这么多人的住址,所以又新来了几个记性好的lookup。这个会影响咱们找到storage住哪吗?答案是不会,因为没有新增别的违章storage建筑,咱们不需要问路也能找着人。

按照以上推论,一定要避免同时增加lookup和storage节点,这很可能会损失数据。

参考网页

7 Replies to “LightCloud的设计原理”

  1. 查询呢?上次看到有人说mysql这种关系型数据库可以很轻松组织数据,但是像lightcloud可行吗?并,这个可以直接投入生产环境使用吗?

  2. NoSQL数据库可以在某些场合代替mysql,需要根据自己的实际情况考量。

    python版的lightcloud在plurk的生产环境中已经使用很长时间,性能和负载占用的表现也不错。但是我写的litecloud还不算完善,不建议投入生产环境使用。

  3. 有几个疑问:
    1.通过LookupRing来找到StorageNode上的数据后,是否需要对数据做一次迁移?把数据从旧的存储节点转移到新的存储节点,同时修改LookupNode中的指向?理论上是需要做的,否则在破坏节点的数据平衡,不过我粗粗算了下,需要6次操作才能完成。
    2.LookupRing是否能简化成一组Lookup节点组?
    3.Ketama比市面上常见的一致性哈希程序性能高很多,但貌似没有原生支持回溯映射列表,当然通过动态修改配置应该可以获得回溯列表。不过我看你代码里没有类似LightCloud回溯3个节点来反向匹配节点,这样LookupRing的扩展能力似乎就大大减弱?
    4.其实我最疑惑的问题是,不管用什么一致性哈希算法,如果支持返回回溯列表,我总觉得LookupRing没有什么存在的必要。假设我能回溯一个key的N个节点,通过遍历这个列表同样能最大程度找到这个key对应的存储节点和值,通过LookupRing来实现,是否画蛇添足了?

    LightCloud的资料好像不是很多,也没有去看他源码,能看到的都是本文一致的文章。有什么误解请指教。

  4. 1. 我从LightCloud的源码里没有找到数据迁移的动作,一般逻辑也就是直接根据hash算法直接从StorageNode寻找数据,如果没找到才从LookupRing寻找记录。
    2. 最简的模型可以使用一组Lookup节点,但是扩充的时候会面临StorgeNode扩容时相同的问题
    3. 没太明白
    4. LookupRing的存在主要就是为了动态增加StorageNode,如果不考虑增加存储节点,当然不需要LookupRing

Leave a Reply

Your email address will not be published.