@erix技术极客TechBooster
好久没有写新文了,原因当然是最近较忙了。当然,终于想到如何可以有效管理时间,兼顾工作,兴趣之法。
好了,本文将主要简单了解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