21.1 nosql介绍
NoSQL(Not Only SQL)意即“不仅仅是SQL”,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。与之相对应的关系型数据库代表是:mysql、oracle、sql server等。
对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当量非常大的时候就很耗费时间和资源,尤其是数据是需要从磁盘里去检索
NoSQL数据库存储原理非常简单(典型的数据类型为k-v),不存在繁杂的关系链。比如像关系型数据库mysql在查询的时候,就得需要去找到对应的库 >>> 表(通常是多个表) >>> 字段,经过这样的一个过程才能查找到相应的数据。
NoSQL除了存储原理简单,而且NoSQL数据还可以存储在内存里,查询速度非常快。NoSQL在性能表现上虽然能优于关系型数据库,但是它并不能完全替代关系型数据库,因为有些应用需要复杂的关系链,那么NoSQL就无法胜任了。NoSQL因为没有复杂的关系、数据结构,扩展非常容易,支持分布式等应用,例如最经常被应用于分布式缓存。
常见NoSQL数据库:
- k-v形式的:memcached、redis 适合储存用户信息,比如会话(session)、配置文件、参数、购物车等等。这些信息一般都和ID(键)挂钩,这种情景下键值数据库是个很好的选择。
- 文档数据库:mongodb 将数据以文档的形式储存。每个文档都是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML、JSON或者JSONB等多种形式存储。
- 列存储 Hbase
- 图 Neo4J、Infinite Graph、OrientDB
21.2 memrcached介绍
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcached是国外社区网站LiveJournal团队开发,其最新版本发布于2010年,作者为Anatoly Vorobey和Brad Fitzpatrick。目的是为了通过缓存数据库查询结果,减少数据库访问次数,从而提高动态web站点性能。官方站点 http://www.memcached.org/
Memcached 特点:
- 数据结构简单(k-v),数据存放在内存里,所以数据不是持久化存储的,不能落地。这意味着重启服务器或者重启Memcached服务就会丢失原来存储的数据。所以在重启前需要先把数据写到磁盘之后再重启才能保证数据不丢失。
- 多线程
- 基于c/s架构,协议简单
- 基于libevent的事件处理
- 自主内存存储处理(slab allowcation)
- 数据过期方式:Lazy Expiration 和 LRU
Memcached的数据流向:
Slab Allocation的原理:
- 将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合),每个chunk集合被称为slab。
- Memcached的内存分配以Page为单位,Page默认值为1M,可以在启动时通过-I参数来指定。
- Slab是由多个Page组成的,Page按照指定大小切割成多个chunk。
Growth factor:
- Memcached在启动时通过-f选项可以指定 Growth Factor 增长因子。该值控制 chunk 大小的差异。默认值为1.25。
- 通过 memcached-tool 命令查看指定 Memcached 实例的不同 slab 状态,可以看到各 Item 所占大小( chunk 大小)差距为1.25
- 命令:# memcached-tool 127.0.0.1:11211 display
Memcached的数据过期方式:
- Lazy Expiration :
- Memcached 内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,Memcached不会在过期监视上耗费CPU时间。
- LRU:
- Memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当内存空间不足时(无法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。
21.3 安装memcached
memcached可以通过yum安装,当然也可以去官网下载相应的源码包进行编译安装,如果是初次接触的话,先用最简单的安装方式或许会比较好一点,先来看看yum中可以安装的memcached版本:
代码语言:javascript复制[root@server ~]# yum list |grep memcached
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
libmemcached.i686 1.0.16-5.el7 base
libmemcached.x86_64 1.0.16-5.el7 base
libmemcached-devel.i686 1.0.16-5.el7 base
libmemcached-devel.x86_64 1.0.16-5.el7 base
memcached.x86_64 1.4.15-10.el7_3.1 base
memcached-devel.i686 1.4.15-10.el7_3.1 base
memcached-devel.x86_64 1.4.15-10.el7_3.1 base
opensips-memcached.x86_64 1.10.5-3.el7 epel
php-ZendFramework-Cache-Backend-Libmemcached.noarch
php-pecl-memcached.x86_64 2.2.0-1.el7 epel
python-memcached.noarch 1.48-4.el7 base
uwsgi-router-memcached.x86_64 2.0.15-1.el7 epel
[root@server ~]#
安装命令:
yum install -y memcached libmemcached libevent
启动memcached服务:
systemctl start memcached
查看进程:
代码语言:javascript复制[root@server ~]# ps aux |grep memcached
memcach 7578 0.0 0.0 325564 1180 ? Ssl 10:52 0:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
root 7585 0.0 0.0 112668 980 pts/0 S 10:52 0:00 grep --color=auto memcached
[root@server ~]#
-u指定运行该服务的用户,-p指定监听端口,-m指定分配给这个进程的内存大小,单位是m,-c指定最大并发数量
查看端口:
代码语言:javascript复制[root@server ~]# netstat -lntp |grep memcached
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 7578/memcached
tcp6 0 0 :::11211 :::* LISTEN 7578/memcached
[root@server ~]#
有两种方式可以更改memcached的服务参数,第一种是使用绝对路径来启动,然后通过选项来指定参数,例如:
/usr/bin/memcached -u memcached -p 11200 -m 32 -c 2024
第二种方式是修改配置文件:
代码语言:javascript复制[root@server ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
[root@server ~]#
如果需要加上监听的ip,可以把OPTIONS="" 改为OPTIONS="127.0.0.1"
21.4 查看memcached状态
memcached里有一个memcached-tool,这个工具是用来查看memcached的状态的,如下示例:
代码语言:javascript复制[root@server ~]# memcached-tool 127.0.0.1:11211 stats
#127.0.0.1:11211 Field Value
accepting_conns 1
auth_cmds 0
auth_errors 0
bytes 0
bytes_read 7
bytes_written 0
cas_badval 0
cas_hits 0
cas_misses 0
cmd_flush 0
cmd_get 0
cmd_set 0
cmd_touch 0
conn_yields 0
connection_structures 11
curr_connections 10
curr_items 0
decr_hits 0
decr_misses 0
delete_hits 0
delete_misses 0
evicted_unfetched 0
evictions 0
expired_unfetched 0
get_hits 0
get_misses 0
hash_bytes 524288
hash_is_expanding 0
hash_power_level 16
incr_hits 0
incr_misses 0
libevent 2.0.21-stable
limit_maxbytes 67108864
listen_disabled_num 0
pid 7578
pointer_size 64
reclaimed 0
reserved_fds 20
rusage_system 0.022575
rusage_user 0.038378
threads 4
time 1514345941
total_connections 11
total_items 0
touch_hits 0
touch_misses 0
uptime 2790
version 1.4.15
[root@server ~]#
我们平时需要关注get_hits(命中数量)以及curr_items(存在memcached中的项目)的值,使用get_hits的值除以curr_items的值,可以计算出命中率。这是为了检测memcached是否有缓存了数据以及是否能被正常的访问这些缓存的数据。
除了memcached-tool之外,还可以使用nc来查看memcached的状态,安装命令如下:
yum install -y nc
查看状态的命令如下:
代码语言:javascript复制[root@server ~]# echo stats |nc 127.0.0.1 11211
STAT pid 7578
STAT uptime 3355
STAT time 1514346506
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.048675
STAT rusage_system 0.025295
STAT curr_connections 10
STAT total_connections 12
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 13
STAT bytes_written 1025
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
END
[root@server ~]#
这和使用memcached-tool来查看的效果基本上是差不多的。
若安装libmemcached了,还可以使用如下命令查看memcached服务状态:
代码语言:javascript复制[root@server ~]# memstat --servers=127.0.0.1:11211
Server: 127.0.0.1 (11211)
pid: 7578
uptime: 3481
time: 1514346632
version: 1.4.15
libevent: 2.0.21-stable
pointer_size: 64
rusage_user: 0.050268
rusage_system: 0.026290
curr_connections: 10
total_connections: 13
connection_structures: 11
reserved_fds: 20
cmd_get: 0
cmd_set: 0
cmd_flush: 0
cmd_touch: 0
get_hits: 0
get_misses: 0
delete_misses: 0
delete_hits: 0
incr_misses: 0
incr_hits: 0
decr_misses: 0
decr_hits: 0
cas_misses: 0
cas_hits: 0
cas_badval: 0
touch_hits: 0
touch_misses: 0
auth_cmds: 0
auth_errors: 0
bytes_read: 30
bytes_written: 2070
limit_maxbytes: 67108864
accepting_conns: 1
listen_disabled_num: 0
threads: 4
conn_yields: 0
hash_power_level: 16
hash_bytes: 524288
hash_is_expanding: 0
bytes: 0
curr_items: 0
total_items: 0
expired_unfetched: 0
evicted_unfetched: 0
evictions: 0
reclaimed: 0
[root@server ~]#