Nosql:Memcached

NoSQL(Not Only SQL),泛指非关系型数据库,它的出现告诉我们:适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。

NoSQL简介

关系型数据库的不足

关系型数据库的性能非常高,但是它毕竟是一个通用型的数据库,并不能完全适应所有的用途,具体来说它并不擅长以下处理:
- 大量数据的写入处理
- 为有数据更新的表做索引或表结构变更
- 字段不固定时应用
- 对简单查询需要快速返回结果的处理

这里逐一进行说明:
1. 大量数据的写入处理
  在数据读入方面,由复制产生的主从模式(数据的写入由主数据库负责,数据的读入由从数据库负责),可以比较简单的通过增加从数据库来实现规模化,但是在数据库的写入方面却不是这么简单,例如,考虑把主数据库从一台增加到俩台,做为互相关联复制的二元主数据库来使用,确实这样似乎可以把每台主数据库的负荷减少一半,但是更新处理会发生冲突(同样的数据在俩台服务器同时更新成其他值),可能会造成数据的不一致,为了避免这样的问题,就需要把对某个表的请求分别分配给合适的的主数据库来处理。
  另外也可以考虑把数据库分割开来,分别放在不同的数据库服务器上。数据库分割可以减少每台数据库服务器上的数据量,以便减少磁盘I/O处理,实现内存上的高速处理。但是这样做存储在不同服务器上的表之间就无法进行join处理。
  
2. 为有数据更新的表做索引或表结构变更
  在使用关系型数据库时,为了加快查询速度需要创建索引,为了增加必要的字段就一定需要改变表结构。为了进行这些处理,需要对表进行共享锁定,这期间数据变更(更新,插入,删除)是无法进行的。如果为数据量比较大的表创建索引或者是变更其表结构,就可能会导致长时间内数据无法进行更新。
  
3. 字段不固定时的应用
  如果字段不固定,在实际运用中每次都进行反复的表结构变更时非常痛苦的,也可以预先设定大量的预备字段,但这样的话很容易弄不清楚字段和数据的对应状态。
  
4. 对简单查询需要快速返回结果的处理
  关系型数据库并不擅长对简单的查询快速返回结果,因为关系型数据库是使用SQL进行读取的,它需要对SQL语言进行解析,同时还有对表的的锁定和解锁这样的额外开销。若希望对简单查询进行高速处理,没有必要非用关系型数据库不可。

RDBMS和NoSQL的区别

RDBMS NoSQL
遵循ACID原则(原子性,一致性,独立性,持久性) BASE原则(基本可用,软状态/柔性事务,最终一致性)
结构化查询语言(SQL) 没有标准统一的查询语言
高度组织化结构化数据 非结构化和不可预知的数据
  CAP定理

CAP定理

在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency) (所有节点在同一时间具有相同的数据)
- 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
- 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三大类:
- CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
- CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
cap

NoSQL数据库分类

类型 部分代表 特点
列存储 Hbase
Cassandra
Hypertable
按列存储数据。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势
文档存储 MongoDB
CouchDB
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能
key-value存储 Redis
MemcacheDB
可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收
图存储 Neo4J
FlockDB
图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便
对象存储 db4o
Versant
通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据
xml数据库 BaseX 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath

Memcached

Memcached简介

Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。本质上,它是一个简洁的key-value存储系统。一般使用的目的是通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度,提高可扩展性。
memcached

Memcached特征

memcached的特征:
- 协议简单
memcached的服务器客户端通信使用简单的基于文本行的协议,因此,通过telnet也能在memcached上保存数据,取得数据。

  • 基于libevent的事件处理
    libevent是一个程序库,它将Linux的epoll,BSD类操作系统的kqueue等事件处理功能封装成统一的接口,即使对服务器的连接数增加,也能发挥O(1)的性能。因此memcached能在Linux,BSD等操作系统上发挥其高性能。

  • 内置内存存储方式
    memcached保存的数据都存储在内置的内存存储空间中,由于数据仅存在于内存中,因此重启memcached,重启操作系统会导致全部数据丢失。另外,内容容量达到指定值后,就会基于LRU(最近最少使用)算法自动删除不使用的缓存。

  • memcached不互相通信的分布式
    memcached尽管是分布式缓存服务器,但服务器端并没有分布式功能,各个memcached不会互相通信以共享信息。如何进行分布式,是由客户端来实现的。
    memcached_fenbu
    如上图所示,缓存的存储的一般流程为:当数据到达客户端,客户端实现的算法就会根据”键”来决定保存的memcached服务器,服务器选定后,命令它保存数据。取的时候也一样。客户端根据”键”选择服务器,同样使用之前的算法,这样就能保证读写都是相同的服务器了。

分布式方法

memcached的分布式方法主要有俩种:取模法和一致性hash算法。

  • 取模法
    取模法(余数计算分散法)的算法如下:
CRC($key)%N

该算法下,客户端首先根据key来计算CRC,然后结果对服务器数进行取模得到memcached服务器节点,这种方式有两个问题需要注意:
1. 当选择到的服务器无法连接的时候,一种解决办法是将尝试的连接次数加到key后面,然后重新进行hash,这种做法也叫rehash。
2. 第二个问题也是这种方法的致命的缺点,尽管余数计算分散发相当简单,数据分散也很优秀,当添加或者移除服务器的时候,缓存重组的代价相当大。

  • 一致性hash算法
    Consistent Hashing算法的描述如下:
    首先求出memcached服务器节点的哈希值,并将其分配到0-2^32的圆上,这个圆我们可以把它叫做值域,然后用同样的方法求出存储数据键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上,如果超过0-2^32仍找不到,就会保存在第一台memcached服务器上:
    hash1
    如果新添加或移除一台机器,在consistent Hashing算法下会有什么影响。上图中假设有四个节点,我们再添加一个节点叫node5:
    hash2
    node5被放在了node4与node2之间,本来映射到node2和node4之间的区域都会找到node4,当有node5的时候,node5和node4之间的还是找到node4,而node5和node2之间的此时会找到node5,因此当添加一台服务器的时候受影响的仅仅是node5和node2区间。

  • 优化的一致性hash算法
    可以看出使用consistent Hashing最大限度的抑制了键的重新分配,有的consistent Hashing的实现方式还采用了虚拟节点的思想。问题起源于使用一般hash函数的话,服务器的映射地点的分布非常不均匀,从而导致数据库访问倾斜,大量的key被映射到同一台服务器上。为了避免这个问题,引入了虚拟节点的机制,为每台服务器计算出多个hash值,每个值对应环上的一个节点位置,这种节点叫虚拟节点。而key的映射方式不变,就是多了层从虚拟节点再映射到物理机的过程。这种优化下尽管物理机很少的情况下,只要虚拟节点足够多,也能够使用得key分布的相对均匀。


相关内容推荐