当前位置: 首页 > news >正文

Cassandra的事务支持及数据一致性解决方案

距离上次写博客已有半年之久,上一篇博客(Cassandra in Action with Twitter's Ruby Client)主要是一个关于Cassandra入门的文章,里面没有提到关于数据一致性的处理。这个博客的主要目的就是要提供一个方法来保证数据的一致性。

Cassandra是一个高性能的Key/Value存储服务器,在NoSQL社区相当的有影响力(主要还是因为师出名门,有Amazon和Facebook以及Twitter等撑腰)。我们可以把它想象成一个多级的哈希表,它不存储数据库的设计信息,也就是说它是一个schemaless的数据库。如果你喜欢使用Ruby的话,那我敢保证,当你进入到schemaless的天地后你就再也不愿回到过去。它可以强大到让你产生快感的地步,就好象在高空中自由翱翔一样,没有任何东西阻挡你实现自己的想法。当然,如果因为schemaless,你把数据整的稀巴烂,那就不要怪我,schemaless并不是designless。

好了,我满足了,废话说完了,该说正题了。当你看完Cassandra如何强大之后,通常都会注意到一个坏消息:no transactions。这简直像个晴天霹雳,没有事务支持那岂不是寸步难行了,总不能每次都靠观音菩萨保佑不会产生数据不一致吧。是的,事务对于一个数据库来说相当重要,特别是当我们有数据一致性要求的时候。商业数据库没有哪个是不支持事务的,而且厂商通常都会在这块花费大力气。但Cassandra偏偏就没有,因为它要给你另外的东西而不是事务,它想让你的读写非常快速的执行并且保证数据最终是一致的。但问题是,我爱快速的读写性能,但我也要一致的数据啊,最终一致并不能避免两个进程访问同一资源时的数据丢失,纠结啊!

来看一个简单的例子:一个整数数据,当前值是0,有两个进程同时想让它加1。这两个进程的处理方法应该是一样的,先把当前值读出来,然后加上1,然后写回去。幸运的情况下(就是我前面说的观音菩萨在保佑),两个进程的执行时间上没有overlapping,相互没有影响,那我们得到的就是2。但有时候菩萨出差中,第一个进程读出来后还没有写进去就被第二个进程给和谐了,等它写完后就等于第二个进程的数据丢失了。

要解决一致性的问题,第一个方法就是不要搞那么多的操作进程,而只由一个进程去操作。只要没人跟它抢,就不会有数据丢失的问题。针对上面的问题,我们需要做的就是增加一个队列以及第三个进程。当以前的两个进程想要做“加1”的操作的时候,它们往一个队列里面插入新的记录(在Cassandra里面写是永远不会失败的)以告知第三个进程它们想干嘛。第三个进程相当于是一个代理,专门检查队列里的指令并执行,它负责真正的“加1”操作。

你肯定在想,就这么个简单的操作就要搞这么多名堂,复杂一点的事情可怎么得了?是的,复杂一点的事情就不能这么搞了。更实际的方法是用锁(这其实就是商业数据库的事务处理底层机制),把两个进程的执行时间隔开来。不管是这里的锁还是前面的增加第三个进程,说到底都是需要一个统一的仲裁机构,它是全局唯一的,所以它那里的东西不会打架。提供锁的服务器就是这个全局唯一的仲裁机构,它告诉那两个进程何时可以去修改数据,这样就可以把执行时间分割开来而不至于产生overlapping。呵呵,我们找到观音了!

好消息来了,已经有人做了这方面的工作了哦,大家有免费的锁服务器用诶。如果你习惯Java的话,我们有Cages(http://www.apacheserver.net/Locking-and-transactions-over-Cassandra-using-Cages-i28826.htm)。但不幸的是,我不会java,以前用java写过一些从来没有人真正用过的项目,但没有做过真正的商业开发。而又幸运的事,我找到了一个Ruby的锁服务器:Officer (https://github.com/chadrem/officer)。它是从另外一个开源项目elock(https://github.com/dustin/elock)那里取得灵感后开发出来的。【人生大起大落的太快,实在是太刺激了】

好了,我不罗嗦了。更多的信息,去相关的网站看吧。下一篇博客我准备说一说Cassandra里的schemaless建模技术,应该就在不久的将来。。。SEE U!

相关文章:

  • 表变量和临时表
  • 常见排序算法时间复杂度
  • 老子《道德经》第二十五章
  • SVN
  • sql自定义函数及C#中调用
  • json-lib codehuas copyright
  • 周记 2015.1.17
  • UGUI自适应
  • read 系统调用剖析
  • Android系统之Broadcom GPS 移植
  • 寒假汇编语言作业(4)
  • 使用jni接口完成android本地程序的运行--具体的操作
  • java和c的本质--最重要的是启动
  • 脑子放放电
  • 关于ProjectServer定制化项目中心页面
  • ES6指北【2】—— 箭头函数
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • gulp 教程
  • HashMap剖析之内部结构
  • JavaScript实现分页效果
  • log4j2输出到kafka
  • MySQL几个简单SQL的优化
  • RxJS: 简单入门
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 机器学习中为什么要做归一化normalization
  • 解析带emoji和链接的聊天系统消息
  • 蓝海存储开关机注意事项总结
  • 类orAPI - 收藏集 - 掘金
  • 码农张的Bug人生 - 初来乍到
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 携程小程序初体验
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (Java)【深基9.例1】选举学生会
  • (libusb) usb口自动刷新
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (利用IDEA+Maven)定制属于自己的jar包
  • (七)Java对象在Hibernate持久化层的状态
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (一)WLAN定义和基本架构转
  • (原)Matlab的svmtrain和svmclassify
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .Net Remoting常用部署结构
  • .NET 常见的偏门问题
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 药厂业务系统 CPU爆高分析
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .net快速开发框架源码分享
  • .net中生成excel后调整宽度
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @Data注解的作用