“NOSQL” 杂谈
作者:网络转载 发布时间:[ 2016/9/27 11:01:09 ] 推荐标签:数据库 NOSQL 接口
本文将要为您介绍的是“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由GregWhalin维护的客户端
较早推出的客户端,稳定,持久运行。
DustinSallings实现的基于javanio的Spymemcached
Asimple,asynchronous,single-threadedmemcachedclientwritteninjava.支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常报timeOut等相关异常。
XMemcache
Memcached同样是基于javanio的客户端,javanio相比于传统阻塞io模型来说,有效率高(特别在高并发下)和资源耗费相对较少的优点。传统阻塞IO为了提高效率,需要创建一定数量的连接形成连接池,而nio仅需要一个连接即可(当然,nio也是可以做池化处理),相对来说减少了线程创建和切换的开销,这一点在高并发下特别明显。因此XMemcached与Spymemcached在性能都非常,在某些方面(存储的数据比较小的情况下)Xmemcached比Spymemcached的表现更为,具体可以看这个JavaMemcachedClientsBenchmark。
根据上面的介绍,大概可以了解到,官方提供的是阻塞的客户端,要利用线程池来实现并发,但是官方提供的包还有一个非常致命的问题,不提供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作为同步手段。

sales@spasvo.com