“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是关系型数据库强一致性的四个要求, ...
随机推荐
- 按需加载.js .css文件
首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...
- mysql 学习总结
MYSQL的增.删.查.改 注册.授权 #创建一个对数据库中的表有一些操作权限的用户,其中OPERATION可以用all privileges替换,DBNAME.TABLENAME可以用*替换,表 ...
- 如何利用ansible callback插件对执行结果进行解析
最近在写一个批量巡检工具,利用ansible将脚本推到各个机器上执行,然后将执行的结果以json格式返回来. 如下所示: # ansible node2 -m script -a /root/pyth ...
- Linux之搭建自己的根文件系统
Hi!大家好,我是CrazyCatJack.又和大家见面了.今天给大家带来的是构建Linux下的根文件系统.希望大家看过之后都能构建出符合自己需求的根文件系统^_^ 1.内容概述 1.构造过程 今天给 ...
- 深入理解javascript的getTime方法
1.理解getTime getTime() 方法返回一个时间的格林威治时间数值. 可以使用这个方法把一个日期时间赋值给另一个Date 对象. 语法: dateObj.getTime() 参数: 无. ...
- 灵魂宝石 bzoj 2663
灵魂宝石(1s 128MB)soulgem [问题描述] "作为你们本体的灵魂,为了能够更好的运用魔法,被赋予了既小巧又安全的外形" 我们知道,魔法少女的生命被存放于一个称为灵魂宝 ...
- 子类继承父类时JVM报出Error:Implicit super constructor People() is undefined for default constructor. Must define an explicit constructor
当子类继承父类的时候,若父类没有定义带参的构造方法,则子类可以继承父类的默认构造方法 当父类中定义了带参的构造方法,子类必须显式的调用父类的构造方法 若此时,子类还想调用父类的默认构造方法,必须在父类 ...
- NSStringCompareOptions
typedefNS_OPTIONS(NSUInteger, NSStringCompareOptions) { NSCaseInsensitiveSearch = 1, //不区分大小写比较 N ...
- android Notification介绍
如果要添加一个Notification,可以按照以下几个步骤 1:获取NotificationManager: NotificationManager m_NotificationManager=(N ...
- javaMail
JavaMail概述: JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类.但它并没有包含在JDK中,而是作为JavaEE的一部分. javaMai ...