微信号:gh_f0d5bcf5edd8

介绍:Hadoop;Hive;Spark;Solr;OpenStack;Docker; Kubernetes;Cassandra;Flume;HBase;Kafka;Mesos;Storm;Thrift;ZooKeeper;Kylin etc.

Eventual Consistency & Modules in Redis

2016-08-31 06:52 @erix

好久没有写新文了,原因当然是最近较忙了。当然,终于想到如何可以有效管理时间,兼顾工作,兴趣之法。

好了,本文将主要简单了解Redis的Eventual Consistency与令人期待的Redis Modules新功能。


本文将主要简单了解Redis的Eventual Consistency与令人期待的Redis Module新功能。


1. Eventual Consistency


对于一致性,可以分为从客户端和服务端两个不同的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则 是更新如何复制分布到整个系统,以保证数据最终一致。

我们知道多数分布式系统只能做到Eventual Consistency,即经过一定时间后,所有的node最终达成数据一致(good things will eventually happen)。

下图是典型的多数据中心,最终一致性的实现架构。



有机会也可以介绍我们目前的一个金融系统的架构,全球多数据中心海量数据如何通过EMS,Replication等机制做到最终一致性。


回到Redis, 单机版的Redis保证了CP(Consistency & Partition-Tolerancy), Consistency为强一致性,Redis Cluster在2015年3.0版本中则引入分布式,随之模型则变为支持AP(Avaiability & Partition-Tolerancy),Consistency为最终一致性(Eventual Consistency),无法保证强一致性。


然而,最终一致性并无法解决安全/正确性问题,如最终一致的数据如何选出,万一有数据在“最终一致前”就返回则无法保证其正确性。


Redis Cluster的读写请求只支持Master节点,当一请求在对应的Master写成功后,立刻返回给客户端成功信息,同时Master则通过异步的方式将新的数据同步到对应的Slave, 可以看出在保证了高效的速度下,还是存在数据会丢失的情形:


  • Master在返回客户成功后宕机(从而重新选主,但丢失了刚刚写的记录)

  • 当网络发生脑裂(split-brain)或者partitioned cluster集群分裂为多数派与少数派,如果数据继续写入少数派的Master,则当Cluster感知,并停止少数派Master,或者重新选主时,则面临丢失刚才已写入少数派的数据

对于Redis目前的Eventual Consistency, 如果业务严苛或者需要强一致性,目前只能建议或者选择其它关系型数据库(之后再同步到Redis),或者自行通过WAIT命令,但也只能解决上述问题一,而针对Split-brain目前比较棘手。


2. Redis Modules


可加载模块是Redis的新鲜尝试,可以称之为下一个里程碑,目前应该尚未发布,喜欢尝鲜的同学可以在unstable中体验,Antirez称希望可以在4.0稳定版本中见到。


多年来,Redis作为开源系统,其扩展性对于程序员来讲只能通过七种武器之一的lua脚本,要么直接修改redis源码(很多公司也确实是这么做的,因为一个系统不可能满足所有客户的需求,客户在面临取舍中只好自给自足)。然而lua脚本扩展性有限,并且无法直接访问redis底层的存储数据以及调用底层API;而修改源码则面临自己需要维护版本的问题,即需要不断与redis的分支进行合并。


Redis这个新的可加载模块则希望向Apple AppStore或者Android Marketplace一样,打造一个全新的Redis生态系统,使得开发人员可以编写自己扩展, 可拔插的模块,同时可以访问Redis底层核心API,Antirez对于这个新的尝试自己评价说“It was a matter of time but it eventually happend",Redis的潘多拉魔盒已经打开。


我们来看一个简单事例吧:

Redis扩展模块的形式是很固定的,需要编写且只编写两个部分:注册命令的函数和具体实现命令的函数。


简单来说,外部模块可以引用redismodule.h中的所有API, 包括访问Redis的字典空间,内存访问,调用Redis命令,向客户端返回数据等功能。外部模块最终以动态库的形式被server加载使用,并可以做到启动或者动态加载。可以看出,由于模块仅仅依赖redismodule.h暴露的接口,而并不依赖于实现本身,因此可以兼容redis的版本升级。


Redis模块的初始版本已经支持各种通用可拔插模块,包括全文搜索模块,图像处理,认证模块,安全模块等等。



自动内存管理


我们知道使用C语言开发,或者扩展Redis,编写Redis模块API都需要自己手动管理内存,进行对象内存分配,释放。追求性能之余也增加了复杂性。而当Redis引入模块,支持模块运行于容器环境时,同时也具备了支持自动内存管理的沙箱。果然,Redis开始提供模块中自动内存管理功能,当然以性能著称的Redis在提供此功能时也需要有部分性能损耗,Antirez自己说most of time, a very low cost。


当然,好比你也可以在手自一体的车上,使用手动档,必要时人工管理释放内存,然而,本质上,手自一体的已然是自动变速箱,只是提供了手工变速的体验而已。



总结


本文简单介绍了Redis的最终一致性与尚在开发中的新特性Redis Module, 希望对大家有所参考。另外也参考了Antirez的官网博客,有兴趣的朋友也可以关注。


 

公众号:技术极客TechBooster



 
技术极客TechBooster 更多文章 Apache顶级项目8-Geode源码深度分析 In Practice:一个由CountDownLatch引发的Bug
猜您喜欢 李世石负于 AlphaGo|人工智能日渐强大,未来人类将与它们如何沟通? 【经典面试题】删除字符串 WebDav规范与WebDavServlet的锁的实现 (之一) TLS协议分析 (八) 实现与开源项目 是时候把Android 项目切换到Android Studio