“NOSQL” 杂谈
引言:
nosql 的兴起和革命,在我看来已经开始逐渐影响到了传统的sql的地位,但是仅仅是影响而已,取代是不太可能的。
正文:
两年前,一个偶然的机会开始接触到 nosql ( mongodb )。用来作数据挖掘的存储容器,第一次接触到nosql,真的被它惊艳到了。鄙人受到传统的SQL的思维定势,甚至一时间难以接受。
mongodb是一个非关系型文档数据库,非常适合文档类型的数据的存储,查询也十分方便,支持动态的横向和纵向的数据扩展。爱不释手。下个用几行shell来展示一下mongodb的魅力
show dbs; //无则会创建
use mydb; show collections; //新建集合,相当于mysql中的表
db.createCollection('mycollection'); //插入数据.
db.mycollection.insert({'username':'chenqimiao','age':23}) db.mycollection.insert({'username':'cqm','age':23,'sex':'男'}) //查询
db.mycollection.find({"age":23});
类比mysql的话,最大的区别可能在于表结构或者说集合结构的定义了,mysql的列是预定义的,而mongodb是在插入数据的时候才确定这条数据的列。
所以mongodb可以支持动态扩展列,在mongo中可能不叫列,要叫作域(field)吧。
后来花了一点时间了解了一下 HBase , Habase 诞生于 Hadoop的子项目,受大数据的遗传。单表可以非常的大,同样Habase也是基于列的。
印象中HBase 中有一个非常特别的特性,HBase 的数据覆盖,并不是实际的覆盖。HBase 有一个时间维度的概念,所有的数据都是基于这个维度进行存储的,
简单点说,同样的key 可能在HBase 中存在两个value。它是怎么做到的?因为它给每一条记录都偷偷记录了一个timestamp,每次你去覆盖键值对的时候,你以为你已经删除了旧值,替换成了新
值,而实际上只是再添加了一条记录而已,两条记录共存在一个时间维度上。每次get(key)默认取最新的一个value,仅此而已。
你还可以手动设置失效时间TTL,这样每一个值就会有一个有效期,过了有效期都值是不能get出来了,但是值还是存储在HBase中并未丢失。
再后来接触到了 redis ,相信大家对这个都相当的熟悉,基于内存的缓存数据库,简单的set() get()就可以了缓存一些经常使用到的值,之前我也专门介绍过 redis的安装,shell命令,多实例部署,读写分离,主从复制,哨兵 等等问题。
当数据超过一定量 , redis会把数据swap到文件中去,如果使用到swap中的文件的值,redis会把文件在swap到内存中,进行读写,十分智能。支持的数据类型也比较多 ,除了k-v 还有hset ,hash ,zset等等
最近在做在线课堂,用到了 Memcache ,这个东西基本和redis的使用场景相似,基于内存的nosql。但是支持的数据类型只有k-v的形式。这是不同于redis的一点。
其二的话, Memcache 不支持文件持久化。
其三, memcache 的多实例,是基于客户端的,这个比较有意思要好好聊一聊了,象我们平常接触的mysql,redis,多实例同步基本是读写分离,主从复制,主机写,从机读,这样的模式。可以说是基于服务端的多实例方案。但是 memcache 有点好玩了,它的多实例之间不进行同步,那它是怎么做到负载均衡的时候保证数据的完整性呢?
说到这里,我想先介绍一下memcache的主流的客户端程序(JAVA)
- 官方提供的基于传统阻塞io由Greg Whalin维护的客户端
较早推出的客户端,稳定,持久运行。
- Dustin Sallings实现的基于java nio的Spymemcached
A simple, asynchronous, single-threaded memcached client written in java. 支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常 报timeOut等相关异常。
- XMemcache
Memcached同样是基于java nio的客户端,java nio相比于传统阻塞io模型来说,有效率高(特别在高并发下)和资源耗费相对较少的优点。传统阻塞IO为了提高效率,需要创建一定数量的连接形成连接 池,而nio仅需要一个连接即可(当然,nio也是可以做池化处理),相对来说减少了线程创建和切换的开销,这一点在高并发下特别明显。因此 XMemcached与Spymemcached在性能都非常优秀,在某些方面(存储的数据比较小的情况下)Xmemcached比 Spymemcached的表现更为优秀,具体可以看这个Java Memcached Clients Benchmark。
根据上面的介绍,大概可以了解到,官方提供的是阻塞的客户端,要利用线程池来实现并发,但是官方提供的包还有一个非常致命的问题,不提供 CAS 的同步功能。
什么是 CAS ?
了解过java下面的 java.util.concurrent.atomic; 下面的类的同学应该知道, CAS (check and swap),这是一种乐观锁的实现,程序陷入一个循环,得到旧值,执行CAS方法,传入旧值,新值,若旧值未发生变化 ,则用旧值,换出新值。
while(true){ Object oldValue = atomicObject.get("key1") ; Object newValue = new Object(); Object value = checkAndSwap("key1",oldValue,newValue) ; if(value!=null&&oldValue.equals(value)) break; }
解释完 CAS ,回到刚才的问题,为什么没有实现 CAS ,是官方包一个致命的弱点,明白了 CAS 原理的同学,应该发现其实它就是一个同步的手段,那为什么不能使用 syncronized 的。那是因为数据并发发生在不同项目里面,没有办法给多个项目之前共用一个 syncronized 。这个时候只能利用memcache提供的锁,利用 CAS 作为同步手段。
庆幸spyMemcache和xmemcache都提供了 CAS 的操作。
那么问题来了,刚刚最早提出的问题如何解答?( CAS 多实例同步问题。)其实啊memcache根本不需要进行多实例同步,它的多实例是依赖于客户端程序实现的。
比如spymemcache:
para.memcache.server=192.168.202.121:11211,192.168.202.121:11210 配置两个server即可。其余的操作和操作一个memcache是一摸一样的,客户端会根据Hash散列算法( HashMap 的实现算法)将键值对放到对应的 memcache 中,由于算法一致性,所以存取双方都能得知键值在哪一个 memcache 中。这样就实现了多实例了。
另外spymemcache客户端还有一个比较厉害的地方,它能直接将java对象序列化,作为k-v中的v,get(k)的时候自动反序列化成对象,无需直接操作JSONObject,当然前提是对象实现
Serializable 接口,并给定一个 serialVersionUID 。redis也可以直接存储二进制文件,但是官方提供的客户端程序,并没有封装好序列化和反序列化,需要自己实现。
说了这么多nosql,好像传统sql无用武之地一般。其实传统的sql才是最稳定的,适用面积最广,最安全,并且提供了事务回滚,保证数据一致性,这是nosql为了提高速度,增强扩展性,所要面临的一部分舍弃。
“NOSQL” 杂谈的更多相关文章
- 什么时候该用NoSQL?
: 杂谈 NoSQL这两年越来越热,尤其是大型互联网公司非常热衷这门技术.根据笔者的经验,并不是任何场景,NoSQL都要优于关系型数据库.下面我们来具体聊聊,什么时候使用NoSQL比较给力: 1) ...
- NoSql数据库使用半年后在设计上面的一些心得
NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...
- 非关系型数据库(NoSql)
最近了解了一点非关系型数据库,刚刚接触,觉得这是一个很好的方向,对于大数据 方面的处理,非关系型数据库能起到至关重要的地位.这里我主要是整理了一些前辈的经验,仅供参考. 关系型数据库的特点 1.关系型 ...
- 关系型数据库与NoSQL数据库
关系型数据库的优缺点 优点: 可以做事务处理,从而保证了数据的一致性: 可以进行JOIN等多表查询: 由于以SQL标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处). 缺点: 大量数据的写 ...
- 几款主流 NoSql 数据库的对比
最近小组准备启动一个 node 开源项目,从前端亲和力.大数据下的IO性能.可扩展性几点入手挑选了 NoSql 数据库,但具体使用哪一款产品还需要做一次选型. 我们最终把选项范围缩窄在 HBase.R ...
- Squirrel: 通用SQL、NoSQL客户端
安装 配置数据库 配置驱动 配置连接 如果你的工作中,需要使用到多个数据库,又不想在多种客户端之间切换来切换去.那么就需要找一款支持多数据库的客户端工具了.如果你要连接多个关系型数据库,你就可以使用N ...
- NoSQL和MongoDB
NoSQL(NoSQL=Not Only SQL),意即“不仅仅是SQL”.关系数据库关注在关系上,NoSQL关注在存储上. 发展背景 (1)传统关系型数据库遇到了性能瓶颈. 高并发读写(High ...
- NoSQL指南
一.数据库发展 1.早期出现的数据库包括平面文件数据管理系统.分层数据管理系统和网络数据管理系统,分别对应的数据结构是线性表.树和图. 平面文件数据管理系统是使用磁带对数据进行顺序存储的,带来的问题不 ...
- NoSQL与RDBMS的九点区别联系
原文链接:http://blog.sina.com.cn/s/blog_5373fb0b0101ft8a.html 1 理解ACID与BASE的区别(ACID是关系型数据库强一致性的四个要求, ...
随机推荐
- JavaScript性能优化
如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...
- 【小计】新人Tostring前忘记Null判断的处理
ToString和string.Concat(可屏蔽Null的异常)性能相差不大,一些中小项目完全可以用Concat(新人容易忘记判断Null的情况,遇到太多了,所以建议重写tostring方法,内部 ...
- 3.Windows Server 2012 R2数据库部署
很多人竟然不会安装数据库....好吧,来个图文教程,其实和windows里面一样安装,和安装2008一样的 先安装3.5:http://www.cnblogs.com/dunitian/p/53487 ...
- UWP开发必备:常用数据列表控件汇总比较
今天是想通过实例将UWP开发常用的数据列表做汇总比较,作为以后项目开发参考.UWP开发必备知识点总结请参照[UWP开发必备以及常用知识点总结]. 本次主要讨论以下控件: GridView:用于显示数据 ...
- jsp页面无法识别el表达式的解决方案
今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为${user.username}的表达式语言,在浏览器页面中仍然显示为${user.username},说明jsp根本不 ...
- 通过自定义特性,使用EF6拦截器完成创建人、创建时间、更新人、更新时间的统一赋值(使用数据库服务器时间赋值,接上一篇)
目录: 前言 设计(完成扩展) 实现效果 扩展设计方案 扩展后代码结构 集思广益(问题) 前言: 在上一篇文章我写了如何重建IDbCommandTreeInterceptor来实现创建人.创建时间.更 ...
- 用angular怎么缓存父页面数据
angular做单页面应用是一个比较好的框架,但是它有一定的入门难度,对于新手来说可能会碰到很多坑,也有许多难题,大部分仔细看文档,找社区是能解决的. 但有些问题也许资料比较少,最近遇到过一个要缓存父 ...
- 从贝叶斯到粒子滤波——Round 1
粒子滤波确实是一个挺复杂的东西,从接触粒子滤波到现在半个多月,博主哦勒哇看了N多篇文章,查略了嗨多资料,很多内容都是看了又看,细细斟酌.今日,便在这里验证一下自己的修炼成果,请各位英雄好汉多多指教. ...
- Windows 上安装 Jekyll.
Jekyll是一个静态网站生成工具.它允许用户使用HTML.Markdown或Textile来建立静态页面,然后通过模板引擎Liquid(Liquid Templating Engine)来运行. 原 ...
- EasyPR--开发详解(6)SVM开发详解
在前面的几篇文章中,我们介绍了EasyPR中车牌定位模块的相关内容.本文开始分析车牌定位模块后续步骤的车牌判断模块.车牌判断模块是EasyPR中的基于机器学习模型的一个模块,这个模型就是作者前文中从机 ...