注册
登录

您现在的位置是:首页 > 学无止境

天涯开源key-list类型内存数据引擎——Memlink

木木彡82 2010-11-26 11:07:00 689人围观
天涯社区最近开发了一款数据引擎——Memlink,并将其开源。对于为什么会出现这样一款开源项目、它的能力和市面上的其他款同类型项目相比有怎样的优势,InfoQ中文站特地采访了天涯社区在北京研发中心的技术负责人冯勇先生。

来源:http://www.infoq.com/cn/news/2010/11/tianya-memlink

天涯社区最近开发了一款数据引擎——Memlink ,并将其开源。对于为什么会出现这样一款开源项目、它的能力和市面上的其他款同类型项目相比有怎样的优势,InfoQ中文站特地采访了天涯社区在北京研发中心的技术负责人冯勇先生。

1. 您好,能请您先自我介绍一下吗?您最近在做哪些有趣的事情呢?

大家好!我是天涯技术中心系统平台部负责人冯勇,系统平台部是今年刚组建的部门,旨在优化天涯线上产品的系统架构。天涯是一个有十二年历史的网站,对于一个累积了十二年补丁的系统进行重构、优化,本身就是一件很有趣、很有挑战的事情。

2. 是出于什么初衷,天涯会开发出这样一款数据引擎出来呢?并且最后要开源出来。

近些年,Nosql系统非常流行,也确实对sql系统进行了合理补充,为Web应用提供多种数据解决方案。但是在开源Nosql系统中,key-value系统可选择较多,而key-list/queue系统可选择较少,因此我们开发了memlink来满足我们自己的需要。

在这里,需要强调一些key-list的概念,在实际场景中有大量需要key-list的地方。比如:论坛中的主题列表、回复列表,微博中的用户关注列表、用户feed列表、用户关注feed列表等等。如果使用key-value中的value来存储list(比如:list打包成json放入value中),其操作性能是非常低效的。

理想的Key-list通常需要如下特点:

  1. list是海量的、且操作性能高效
  2. list是有序的、且可动态调整顺序

至于为什么开源?一方面,我们很多工作都得益于已有的开源系统,所以回馈开源社区是我们应做的义务;另一方面,技术分享也有利于公司本身技术的成长,并吸引更多的技术人才。

3. 能介绍一下Memlink的特性吗?

Memlink是一个高性能、持久化、分布式的Key=>List/Queue数据引擎。正如名称中的Mem所示,所有数据都建构在内存中,保证了系统的高性能,同时使用块链进行内存压缩,使用redo-log技术保证数据的持久化。此外,Memlink还支持主从复制、读写分离、数据项过滤操作等功能。

特点:

  • 内存数据引擎,性能极为高效
  • List中的Node采用块链组织,精简内存,优化查找效率
  • Node数据项可自定义Mask表,支持多种过滤操作
  • 支持redo-log,数据持久化,非Cache模式
  • 分布式,主从同步
  • 读写分离,写优先处理。

4. 我们知道市面上还有一些其他基于内存的数据引擎,比如Redis和Scalaris,跟它们相比Memlink解决了什么特别的问题吗?

在设计和开发memlink之前,我们也认真分析对比了Redis。最终没有采用Redis原因有以下四点:

  1. Redis持久化策略(redo-log)不能完全满足线上生产的需求。对于一个成熟的互联网应用应该有足够的容错能力。比如系统统重启、宕机等而不丢失数据。Redis持久化策略一:定时同步磁盘(此期间重启会丢失部分数据);持久化策略二:不断追加log,这样容易使log膨胀,性能降低。Memlink持久化策略是同时借鉴Redis两种策略,在非创建快照期间追加redo-log,在完成快照后清除redo-log。
  2. Redis主从同步策略不够完善。比如:slaver因为某原因丢失了部分同步数据,则需要重新完全获取一份主节点的所有数据。在大数据量的情况下,不太合适线上生产的需求。
  3. Redis单线程模式,读写没有分离,只能使用单核。Memlink为多线程,充分利用多核,并进行了读写分离,优先保证写。
  4. 在内存消耗和性能上Memlink要优于Redis。

Memlink是key=>list/queue引擎,Scalaris是key-value,两者功能出发点上不一样。

5. Memlink在天涯内部的哪些系统中得到了采用?可以提供一下Memlink带来的性能变化的数据吗?

Memlink主要应用于天涯论坛类型产品(论坛、来吧)中。比如论坛的主题列表,当数据达到百万、千万量级,采用Mysql系统进行分页浏览时,基本上不能响应,而Memlink则性能提升了上百倍。具体可见Benchmark

6. 能向广大的开发者朋友们介绍一下,如何来选择一款适用自己的NoSQL产品呢?

首先需要确定业务需求,是否需要NoSQL产品。对于大多数百万量级、千万量级的应用,MySQL也能支持。

其次在明确需要NoSQL产品后,应根据业务需求抽象出数据模型,比如:有些数据是需要采用key-value系统存储,有些数据是需要采用key-list系统存储,有些数据是采用文档数据库存储等等。

对于NoSQL产品候选列表的选项,可以从如下维度进行考虑:

  1. 系统的容量、性能、软硬件环境是否符合需求?
  2. 数据的安全机制如何?各种异常是否会丢失数据?
  3. 具备主从复制功能?何种一致性策略?
  4. 可扩展性?自动扩展 or 程序进行扩展?
  5. 系统的可控性?系统的成熟度、对开发者的支持度、bug谁来修复等等

7. Memlink现在的版本号是多少?未来的发展计划是怎样的?

Memlink现在的版本号为0.2,具备基本key-list/主从复制等功能,目前正在测试中。

在0.3/0.4版本中,Memlink会增加双向队列、用户认证等功能。具体可以见Memlink的RoadMap

长远而言,Memlink专注为一个高性能、持久化、分布式的Key=>List/Queue数据引擎,不会增加其他数据存储模型。

更多关于Memlink的信息,请参考Memlink的介绍文档 设计文档

Memlink 介绍文档

为什么会有Memlink?

对于大型论坛服务,比如百度贴吧、天涯论坛,日均发帖量过百万或千万,日均PV过亿,日积月累下来的帖子数量可能几十亿到上百亿。这种超级论坛,其海量存储、海量访问都是一个非常有挑战性的技术难题。

中小规模的论坛(Phpwind/discuz)通常使用mysql/sql server作为后端存储,当数据量膨胀时,比如一个版面有百万、千万级别主贴,一个主贴下有数百万回复,此时使用SQL语句select … order by … limit … 进行数据查询和展现,性能可想而知。

大型论坛中的数据可以抽象为如下三类数据模型:

  1. Key=>Value结构数据。比如:版面信息、主帖信息、回帖信息等。主贴id对应主贴的信息(标题、发帖时间、作者等等),回帖id对应回贴的信息(回复内容、回复时间、回复者等等)。
  2. Key=>List结构数据。比如:主贴列表,主贴列表按发表时间或者最后回复时间进行排序;回复列表等等。

    Key=>List通常有如下特点:
    1. 可排序
    2. 可动态调整顺序
  3. 其他周边数据(SQL系统/检索系统)。比如:斑竹、会员、友情版面/链接等等,由于数据量较小、逻辑关系较复杂,可以使用sql系统存储;比如帖子检索可以使用检索系统。

对于Key=>Value系统,市面上有较多选择,它们的数据容量大小从数百万到上百亿不等,性能、功能也各有差异,由于讨论KV系统的文章很多,再次不赘述。

对于Key=>List系统,市面上可选择的余地非常小,加之线上工业级别的一些要求,经对比了一些Key=>List系统(Redis),最终选择开发memlink系统,同时开源出来,也希望为业界同行提供多一种选择,繁荣开源社区。

Memlink简介

Memlink是一个高性能、持久化、分布式的Key=>List/Queue数据引擎。正如名称中的Memlink所示,所有数据都建构在内存中,保证了系统的高性能(读性能大约是Redis几倍到十倍),精简内存(内存消耗大约是Redis的1/4),使用了redo-log技术保证数据的持久化。此外,Memlink还支持主从复制、读写分离、数据项过滤操作等功能。

特点:

  • 内存数据引擎,性能极为高效
  • List中的Node采用块链组织,精简内存,优化查找效率
  • Node数据项可定义Mask表,支持多种过滤操作
  • 支持redo-log,数据持久化,非Cache模式
  • 分布式,主从同步
  • 读写分离,写优先处理。

与Redis区别

Redis同样也提供key=>list 存储功能,Memlink与Redis区别有:

  • Redis比较消耗内存。每个存储节点,在不支持vm的情况下要额外消耗12字节内存,在支持vm的情况下,每个节点额外消耗24字节内存。对于存储上亿条数据来说,额外消耗的内存太大。
  • Redis redo-log不够完善。redis提供了两种redo-log机制,机制一:每隔一段时间同步磁盘(此期间重启会丢失部分数据);机制二:追加log方式,会使log文件越来越膨胀,造成性能不优化(需采用额外命令减小log)。
  • 主从同步不完善。如果slaver因为某原因丢失了部分同步数据,需要重新完全获取一份主节点的所有数据。在大数据量的情况下,不太合适线上生产的需求。
  • 网络处理主事件循环只有一个线程,不能很好的利用多核;同时读写没有分离,没有进行写优先处理。
  • List中的Node没有mask表,不能进行一些属性过滤。

Memlink主要对上述特点进行了改进。

性能测试

硬件

  • CentOS release 4.6 (Final)
  • Kernel 2.6.9-67.0.22.ELsmp 32位
  • Memory 4G
  • CPU Intel(R) Xeon(R) CPU E5405 @ 2.00GHz (四核)
  • Disk 250G SATA 

客户端

  • 10个客户端,并发短连接
  • Memlink内部开启4个处理线程。
  • Redis只支持单线程模型。结果表格中的hiredis为使用hiredis客户端测试的结果。redis为官方的redis-benchmark测试结果。
  1w 10w 100w 1000w
insert memlink 9665 9650 10078 10183
hiredis 9381 9489 8993 8976
redis 9285 9290 9287 8835
mysql 5623 5621 5468 5306
range first100 memlink 17400 17504 16614 17292
hiredis 1695 1637 1696 1586
redis 4629 4587 4504 4545
mysql 2210 2286 1955 1611
range first200 memlink 15786 15772 15964 16180
hiredis 711 711 719 692
redis 2941 2949 2941 2857
mysql 1444 1791 1870 1402
range first1000 memlink 3795 3918 3703 3250
hiredis 118 115 116 114
redis 761 739 761 735
mysql 550 692 620 686
range last100 memlink 16989 16502 13118 319
hiredis 2132 240 20 2
redis 4385 191 19 2
mysql 80 8 1 -
range last200 memlink 15915 15596 12203 316
hiredis 743 229 20 2
redis 2941 182 19 2
mysql 94 9 1 -
range last1000 memlink 3893 3641 3332 299
hiredis 120 174 19 2
redis 756 149 18 2
mysql 94 9 1 -

详细性能测试请见Benchmark

Client API

客户端命令描述:

命令名 类型 描述
dump 管理 立即复制一份内存数据到磁盘
clean 管理 重排某个key下的列表
stat 管理 统计信息
create 创建key
del 删除key下的某个value
insert 在key下的列表中插入一条
update 更新key下列表中某value在列表中的位置
mask 修改某个value的mask信息
tag 标记删除列表中的某个value或者恢复某个value
rmkey 删除一个key,包括它的列表
range 获取指定key下的列表中的某个范围的value
count 获取指定key下列表的条数

详细客户端API请见ClientAPI

谁在使用?

目前Memlink应用于天涯来吧、天涯论坛系统。 未来Memlink的Key=>Queue会应用在天涯微博系统上。

未来

Memlink是专注于Key => List/Queue对象的存储系统,它内存使用更精简、性能更高效。 Key => List/Queue系统作为Key => Value另一种形式补充,为高性能、海量数据的Web应用提供了新的数据存储模型选择。

FAQ

  1. 为什么Memlink的读速度会比Redis快?
    这是内部存储数据结构决定的。Redis内部是一个链表。Memlink内部同样是链表,不同的是memlink把N个节点组织到了一个链表数据块内,这样循环查找位置的时候,Memlink理论上最好情况,循环次数比Redis少N倍(N可配置,默认为100)。
  2. 为什么在多线程并发的情况下Memlink比Redis读速度快很多?
    因为Memlink读数据是完全多线程的,并且没有同步锁,可以利用到多核。而Redis在读取数据上是单核的。

其他:

Memlink 项目主页:http://code.google.com/p/memlink

介绍文档:http://code.google.com/p/memlink/wiki/Introduce

详细设计:http://code.google.com/p/memlink/wiki/DesignDocument

性能测试:http://code.google.com/p/memlink/wiki/Benchmark

操作API:http://code.google.com/p/memlink/wiki/ClientAPI

代码下载:http://memlink.googlecode.com/svn/trunk/

文章评论

  • 登录后评论

点击排行