前期一直用的数据库mysql,属于关系型数据库。现介绍一款非关系型数据库——NoSQL;NoSQL=Not Only SQL,意为“不只仅是SQL”,即非关系型数据库。php
- 关系型数据库:
例如京东或者淘宝这些大型电商平台,有着很庞大的数据结构体系,有用户表,商品表,用户信息,商品信息,等当产生一个订单的时候,或者查询数据,是哪一个用户,在什么时间,购买了哪些商品,当调取一个用户在某个时间买了什么东西的时候这些数据是存在必定的关联的。mysql
- 非关系型数据库:
NoSQL的存在就是不须要这些错综复杂的理念,一个key对应一个value。例如一个用户下对应着他的采购订单。且数据所有存在闪存中。不须要再次从磁盘中调取。nginx
NoSQL是不能够替代Mysql独立存在的。例如现实运维环境中,咱们一台WEB安装了一个Discuz,随着访问量的增长,数据库扛不住那么大的压力;怎么办呢?咱们设置一个NoSQL,当用户读取完毕后会直接放在NoSQL中,当用户再次读取的时候,会直接从缓存中读取,不须要再次从数据库中读取。帖子的ID就相似于Key,帖子的内容就相似于Value。web
NoSQL由于没有复杂的数据结构,扩展很是容易,支持分布式。因此扩展也比较容易。若是你的A服务器受到瓶颈,增长服务器让让其继续缓存呗,由于不像关系型数据库须要互相关联,NoSQL直接横向扩展便可!redis
mysql的话只有前面说到的主主,主从,多主多从针对从进行负载均衡。要么就是分库分表,前提是关联的数据库不能够分开,不关联的数据库能够分开。算法
- k-v形式的:memcached、redis
适合储存用户信息,好比会话、配置文件、参数、购物车等等。这些信息通常都和ID(键)挂钩,这种情景下键值数据库是个很好的选择。sql
- 文档数据库:mongodb
将数据以文档的形式储存。每一个文档都是一系列数据项的集合。每一个数据项都有一个名称与对应的值,值既能够是简单的数据类型,如字符串、数字和日期等;也能够是复杂的类型,若有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性能够是不一样的,数据可使用XML、JSON或者JSONB等多种形式存储。mongodb
列存储: Hbase数据库
图存储: Neo4J、Infinite Graph、OrientDBjson
Memcached是国外社区网站LiveJournal团队开发,目的是为了经过缓存数据库查询结果,减小数据库访问次数,从而提升动态web站点性能。
常规做业流程是:用户发起请求给NGINX,而后再次调用PHP,PHP和mysql打交道,当用户PHP获取到请求转给NGINX,NGINX再次把请求数据交给用户。
若是并发量很大,请求mysql的队列比较多,耗费资源,时间。
所以如图,增长一个缓存层Memcached。这样访问过的数据所有丢在缓存中,当再次请求这个数据的时候就直接从Memcached读取,少数据库访问次数,以提升动态web应用的速度、提升可扩展性。
其原理为:
将分配的内存分割成各类尺寸的块(chunk), 并把尺寸相同的块分红组(chunk的集合),每一个chunk集合被称为slab。
Memcached的内存分配以Page为单位,Page默认值为1M,能够在启动时经过-I 参数来指定。
Slab是由多个Page组成的,Page按照指定大小切割成多个chunk。
Memcached的数据过时方式,有两种形式:
- Lazy Expiration
Memcached 内部不会监视记录是否过时,而是在get时查看记录的时间戳,检查记录是否过时。这种技术被称为lazy(惰性)expiration。所以,Memcached不会在过时监视上耗费CPU时间。
- LRU
Memcached会优先使用已超时的记录的空间,但即便如此,也会发生追加新记录时空间不足的状况,此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。所以,当内存空间不足时(没法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。
安装、启动memcached
[root@ying01 ~]# yum install -y memcached [root@ying01 ~]# systemctl start memcached
查看端口、以及进程
[root@ying01 ~]# netstat -lntp |grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 1326/memcached tcp6 0 0 :::11211 :::* LISTEN 1326/memcached [root@ying01 ~]# ps aux |grep memcache memcach+ 1326 0.0 0.3 325604 3244 ? Ssl 11:44 0:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024 root 1338 0.0 0.0 112720 984 pts/0 S+ 11:46 0:00 grep --color=auto memcache [root@ying01 ~]#
上面进程中,能够看到默认的启动信息
/usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
此为默认启动设置:p 端口 m 64M -c 指定最大并发数 -u指定运行memcached服务的用户
能够更改其默认设置:
[root@ying01 ~]# vim /etc/sysconfig/memcached PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" OPTIONS="127.0.0.1" //更改成监控ip
[root@ying01 ~]# /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
用命令 memcached-tool 127.0.0.1:11211 stats
[root@ying01 ~]# memcached-tool 127.0.0.1:11211 stats |head -5 #127.0.0.1:11211 Field Value accepting_conns 1 auth_cmds 0 auth_errors 0 bytes 0
还能够用此命令:echo stats |nc 127.0.0.1 11211
[root@ying01 ~]# yum install -y nc //主要安装nc [root@ying01 ~]# echo stats |nc 127.0.0.1 11211 | head -5 STAT pid 1326 STAT uptime 924 STAT time 1534910395 STAT version 1.4.15 STAT libevent 2.0.21-stable
此命令也能够: memstat --servers=127.0.0.1:11211
[root@ying01 ~]# yum install -y libmemcached //若没有安装,请安装 [root@ying01 ~]# memstat --servers=127.0.0.1:11211 |head -5 Server: 127.0.0.1 (11211) pid: 1326 uptime: 992 time: 1534910463 version: 1.4.15
Memcached相似于mysql同样,一样支持相似于mysql中建立一个库,建立一个表,插入一个表,查看表数据等。
首先须要安装 telnet 命令
[root@ying01 ~]# yum install -y telnet
链接 Memcached,进行一些操做:
[root@ying01 ~]# telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. set key2 0 30 2 //设置 key2 数值,30秒过时,2字节 12 //此时输入任意2字节 STORED //系统表示已储存 get key2 //查看key2的内容 VALUE key2 0 2 12 END get key2 //再次查看key2,已经没有数值,由于过时时间为30秒 END
简单释义:
手动存储一个数据: set key2 0 30 2
其中key2 表明着 key值
- 0表明着 flags 标记
- 30表明着 过时时间
- 2表明着 2个字节
Memcached语法标准格式:
<command name> <key> <flags> <exptime> <bytes>\r\n <data block>\r\n
- 注:\r\n在windows下是Enter键
- <command name> 能够是set, add, replace
- set表示按照相应的<key>存储该数据,没有的时候增长,有的时候覆盖
- add表示按照相应的<key>添加该数据,可是若是该<key>已经存在则会操做失败
- replace表示按照相应的<key>替换数据,可是若是该<key>不存在则操做失败。
- <key> 客户端须要保存数据的key
- <flags> 是一个16位的无符号的整数(以十进制的方式表示)。该标志将和须要存储的数据一块儿存储,并在客户端get数据时返回。客户端能够将此标志用作特殊用途,此标志对服务器来讲是不透明的。
- <exptime> 为过时的时间。若为0表示存储的数据永远不过时(但可被服务器算法:LRU 等替换)。若是非0(unix时间或者距离此时的秒数),当过时后,服务器能够保证用户得不到该数据(以服务器时间为标准)。
- <bytes> 须要存储的字节数,当用户但愿存储空数据时<bytes>能够为0
- <data block>须要存储的内容,输入完成后,最后客户端须要加上\r\n(直接点击Enter)做为结束标志。
演示以上命令 注意:在telnet模式下,使用“Ctrl + Backspace键删除”
set key5 1 60 3 //存储一个3字节值 www STORED get key5 //查询key5的值 VALUE key5 1 3 www END replace key5 1 200 6 //替换key5的值 www123 STORED get key5 //查询替换后的值 VALUE key5 1 6 www123 END delete key5 //删除key5的值 DELETED get key5 END
memcached命令删除 : Ctrl + Backspace
memcached退出 : ctrl+] 而后 quit
set ok 1 0 5 ^] telnet> quit Connection closed. [root@ying01 ~]#
经过查看其状态,能够看到set 、 get 等操做数据
[root@ying01 ~]# memstat --servers=127.0.0.1:11211 //查看状态,里面有记录的 cmd_get: 4 cmd_set: 6 cmd_flush: 0 cmd_touch: 0 get_hits: 1 get_misses: 1 delete_misses: 3 delete_hits: 0
查看内容,结果消失了,说明过时了;
[root@ying01 ~]# memcached-tool 127.0.0.1:11211 dump Dumping memcache contents Number of buckets: 0 Number of items :
此时再次进入memcached,建立数据,再查看
[root@ying01 ~]# telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. set name 1 200 5 //设置过时时间200s 12345 STORED get name VALUE name 1 5 12345 END ^] telnet> quit Connection closed. [root@ying01 ~]# memcached-tool 127.0.0.1:11211 dump Dumping memcache contents Number of buckets: 1 Number of items : 1 Dumping bucket 1 - 1 total items add name 1 1534913629 5 12345
导出数据
[root@ying01 ~]# memcached-tool 127.0.0.1:11211 dump > data.txt Dumping memcache contents Number of buckets: 1 Number of items : 1 Dumping bucket 1 - 1 total items [root@ying01 ~]# ls data.txt data.txt [root@ying01 ~]# cat data.txt add name 1 1534913629 5 12345
导出数据
[root@ying01 ~]# nc 127.0.0.1 11211 < data.txt //由于在 200s内,因此能够导入 STORED
**注意:**导出的数据是带有一个时间戳的,这个时间戳就是该条数据过时的时间点,若是当前时间已经超过该时间戳,那么是导入不进去的。
下载memcache包、解压
[root@xavi ~]# cd /usr/local/src [root@xavi src]# wget http://www.apelearn.com/bbs/data/attachment/forum/memcache-2.2.3.tgz [root@ying01 src]# tar zxf memcache-2.2.3.tgz [root@ying01 src]# cd memcache-2.2.3 [root@ying01 memcache-2.2.3]# /usr/local/php-fpm/bin/phpize Configuring for: PHP Api Version: 20131106 Zend Module Api No: 20131226 Zend Extension Api No: 220131226
执行配置文件并编译
[root@ying01 memcache-2.2.3]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config [root@ying01 memcache-2.2.3]# make [root@ying01 memcache-2.2.3]# make install
查看 生成so文件
[root@ying01 memcache-2.2.3]# ls /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/ memcache.so opcache.a opcache.so
在php.ini添加此语句,让调用此扩展模块
[root@ying01 memcache-2.2.3]# vim /usr/local/php-fpm/etc/php.ini extension="memcache.so" //添加此语句
查看其是否存在
[root@ying01 memcache-2.2.3]# /usr/local/php-fpm/sbin/php-fpm -m [PHP Modules] cgi-fcgi Core ctype curl date dom ereg exif fileinfo filter ftp gd hash iconv json libxml mbstring mcrypt memcache //模块已经在 PHP Modules 里面 mysql
查看1.php内容
[root@ying01 memcache-2.2.3]# curl www.apelearn.com/study_v2/.memcache.txt > 1.php 2>/dev/null //下载 写入 [root@ying01 memcache-2.2.3]# cat 1.php <?php //链接Memcache Memcache $mem = new Memcache; $mem->connect("localhost", 11211); //保存数据 $mem->set('key1', 'This is first value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: " . $val ."<br>"; //替换数据 $mem->replace('key1', 'This is replace value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: " . $val . "<br>"; //保存数组数据 $arr = array('aaa', 'bbb', 'ccc', 'ddd'); $mem->set('key2', $arr, 0, 60); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "<br>"; //删除数据 $mem->delete('key1'); $val = $mem->get('key1'); echo "Get key1 value: " . $val . "<br>"; //清除全部数据 $mem->flush(); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "<br>"; //关闭链接 $mem->close(); ?>
执行此php
[root@ying01 memcache-2.2.3]# /usr/local/php-fpm/bin/php 1.php Get key1 value: This is first value<br>Get key1 value: This is replace value<br>Get key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd ) <br>Get key1 value: <br>Get key2 value: <br>[root@ying01 memcache-2.2.3]#
应用场景:为LNMP架构下作的负载均衡。
假如第一次登陆是在A服务器上,第二次登陆是在B服务器上,假如使用的是nginx代理upstream可使用ip_hash;若是使用LVS呢?
解决方法是:把session不存在服务器的磁盘上,而是存在memcached上去。memcached做为一个公共的服务器,任何web服务器均可以链接!
[root@ying01 ~]# wget http://study.lishiming.net/.mem_se.txt //下载此存session的脚本 [root@ying01 ~]# vim .mem_se.txt <?php session_start(); if (!isset($_SESSION['TEST'])) { $_SESSION['TEST'] = time(); } $_SESSION['TEST3'] = time(); print $_SESSION['TEST']; print "<br><br>"; print $_SESSION['TEST3']; print "<br><br>"; print session_id(); ?>