一、NoSQL介绍

1、NoSQL介绍

NoSQL属于非关系型数据,mysql属于关系型数据库。

对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当数据量非常大的时候就很耗费时间和资源,尤其是需要从磁盘里去检索。

NoSQL数据库存储原理非常简单(典型的数据类型为k-v),不存在繁杂的关系链,比如mysql查询的时候,需要找到对应的库、表(通常是多个表)以及字段。

NoSQL数据可以存储在内存里,查询速度非常快

NoSQL在性能上虽然由于关系型数据库,但是并不能完成替代关系型数据库。

NoSQL因为没有复杂的数据结构,扩展非常容易,支持分布式。

2、常见的NoSQL数据库

k-v(键-值)形式的:memcached、redis,适合存储用户信息,比如会话、配置文件、参数、购物车等等。这些信息一般都和id(键)挂钩。

文档数据库:mongodb,将数据以文档的形式存储。每个文档都是一系列数据项的集合。每个数据项都有一个名称与对应的值,值即可以是简单数据类型,如字符串、数字、日期等,也可以是复制的类型,如有序列表和关联对象。数据存储的最小单位是文档。同一表中存储的文档属性可以是不同的,数据可以使用xml、json或jsonb等形式存储。

列存储:Hbase

图:Neo4j、Infinite Graph、OrientDB

二、memcached介绍

1、memcached

memcached是国外社区网站LiveJournal团队开发的,是用C语言编写的,目的是为了通过缓存数据库查询结果,减少数据库访问次数,从而提高动态web站点性能。

特点:

数据结果简单(k-v),数据存储在内存里

多线程

基于C/S架构,协议简单

基于libevent的事件处理

自主内存存储处理(slab allocation)

数据过期方式:Lazy Expiration和LRU

2、slab  allocation原理

将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合),每个chunk集合称为slab。

memcached的内存分配以page为单位,Page默认值为1M,可以在启动时通过-I参数来指定。

slab是由过个page组成的,page按照指定大小切割成多个chunk。

3、Growth factor

memcached在启动时通过-f选项可以指定Growth faxtor因子。该值控制chunk大小的差异。默认为1.25。

通过memcached-tool命令查看memcached实例的不同slab状态,可以看到各Item所占大小(chunk大小)差距为1.25。

命令:memcached-tool 127.0.0.1:11211 display

4、数据过期方式

Lazy Expiration:memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术成为lazy(惰性) expiration。因此,memcached不会在过期监视上消耗CPU时间。

LRU:memcached会优先使用已超时的记录的时间,但即便如此,也会发生追加新记录时空间不足的情况,此时就要使用名为Least Recently Userd(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当内存空间不足时(无法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。

三、安装memcached

系统:RHEL 7.5(最小化安装),ip:192.168.10.205

1、安装依赖包

[root@node1 ~]#  yum install -y gcc libevent-devel

2、下载memcached包

[root@node1 ~]# curl -O http://www.memcached.org/files/memcached-1.5.9.tar.gz

3、解压、编译、安装

[root@node1 ~]# tar xf memcached-1.5.9.tar.gz 
[root@node1 ~]# cd memcached-1.5.9
[root@node1 memcached-1.5.9]# ./configure --prefix=/usr/local/memcached --sysconfdir=/usr/local/memcached/etc/ --with-libevent && make && make install

4、复制启动文件

[root@node1 memcached-1.5.9]# cp scripts/memcached.sysv /etc/rc.d/init.d/memcached
[root@node1 memcached-1.5.9]# chmod +x /etc/rc.d/init.d/memcached
[root@node1 memcached-1.5.9]# vim  /etc/rc.d/init.d/memcached
...
daemon /usr/local/memcached/bin/memcached
...
[root@node1 memcached-1.5.9]# chkconfig --add memcached
[root@node1 memcached-1.5.9]#

修改/etc/rc.d/init.d/memcached文件:

daemon  memcached 改为 daemon /usr/local/memcached/bin/memcached

5、复制配置文件

[root@node1 ~]# mkdir /usr/local/memcached/etc
[root@node1 memcached-1.5.9]# cp scripts/memcached.sysconfig  /usr/local/memcached/etc/
[root@node1 memcached-1.5.9]#

6、创建memcached pid文件存放目录

[root@node1 ~]# mkdir /var/run/memcached
[root@node1 ~]# chmod 777 /var/run/memcached

7、设置环境变量

[root@node1 ~]# echo "PATH=/usr/local/memcached/bin:$PATH" > /etc/profile.d/memcached.sh
[root@node1 ~]# source /etc/profile.d/memcached.sh
[root@node1 ~]#

8、启动memcached

[root@node1 ~]# memcached -u root -d -m 16m -c 8192
[root@node1 ~]#

启动选项:

进程与连接设置:

-d:以守护进程(daemon)方式运行

-u:指定运行的用户

-I:指定监听的地址

-p:指定端口,默认为11211

-P:指定pid文件

内存相关:

-m:指定可以缓存数据的最大内存,默认为64M

-M:memcached内存不够时禁止LRU,如果内存满了会报错

-n:为key+value+flags分配最小的内存空间,默认48字节

-f:chunk size增长因子,默认1.25

-L:启用大内存页,可以降低内存消耗,改进性能

并发连接设置:

-c:最大的并发连接数,默认是1024

-t:线程数,默认是4

-R:每个event最大请求数,默认是20

-C:禁用CAS(可以禁止版本计数,减少开销)

调试参数:

-v:打印较少的errors/warings

-vv:打印非常多调试信息和错误输出到控制台,也打印客户端命令及响应

-vvv:打印极多调试信息和错误输出,也打印内部状态转变

四、查看memcached状态

编译安装的会缺少一些命令工具。下面使用的是yum安装

[root@node1 ~]# systemctl stop memcached
[root@node1 ~]# yum install memcached -y
[root@node1 ~]# memcached -u root -d -c 8192

查看状态memcached-tool

[root@node1 ~]# 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           3
...

或者使用nc查看,需安装nc

[root@node1 ~]# yum install -y nc
[root@node1 ~]# echo stats | nc 127.0.0.1 11211
STAT pid 1962
STAT uptime 1096
STAT time 1532222623
STAT version 1.5.9
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.042456
STAT rusage_system 0.283043
STAT max_connections 8192
STAT curr_connections 2
STAT total_connections 4
STAT rejected_connections 0
STAT connection_structures 3
STAT reserved_fds 20
STAT cmd_get 0
...

使用libmemcached:

[root@node1 ~]# yum install libmemcached -y
[root@node1 ~]# memstat --servers=127.0.0.1:11211
Server: 127.0.0.1 (11211)
	 pid: 1962
	 uptime: 1205
	 time: 1532222732
	 version: 1.5.9
	 libevent: 2.0.21-stable
	 pointer_size: 64
	 rusage_user: 0.044568
	 rusage_system: 0.302073
	 max_connections: 8192
	 curr_connections: 2
	 total_connections: 5
...

五、memcached命令行

1、安装使用telnet

[root@node1 ~]# yum install telnet -y

2、memcached命令

[root@node1 ~]# 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
12
STORED
set key1 0 30 3
12
123
CLIENT_ERROR bad data chunk
ERROR
abc       
ERROR
set key1 0 30 3
abc
STORED
get key2
END
get key1
VALUE key1 0 3
abc
END

语法:

<command name><key><flags><exptime><bytes>rn

<datablock>rn

<status>rn

rn:Windows的回车键

参数解释:

command name:命令的名称

    set:按照对应的<key>存储数据,如没有则增加,如已经存在则覆盖

    add:按照对应的<key>存储数据,如已经存在则会操作失败

    replace:按照对应的<key>数据替换,如已经存在则会操作失败

    append:往后追加

    prepend:往前追加

key:需要保存数据的key,普通字符串,要求小于250个字符,不包含空格和控制字符

flags:是一个16位的无符号的整数(以十进制的方式表示),客户端用来标识数据格式的数值。

<exptime>:过期时间,单位:秒。0表示永远不过期(但可以被fu wu器算法LRU替换)

<bytes>:需要存储的字节数,当用户希望存储空数据是可以设为0

<datablock>:需要存储的内容。

<status>:状态

set haha 0 50 2
11
STORED
replace haha 1 100 3
123
STORED
get haha
VALUE haha 1 3
123
END
quit

quit:退出

六、memcached数据导出和导入

1、导出数据:

[root@node1 ~]# 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@node1 ~]#

2、导入数据:

[root@node1 ~]# nc 127.0.0.1 11211 < data.txt 
NOT_STORED
[root@node1 ~]#

NOT_STORED:失败了,因为原来已经有数据了。

对于设置有效期的值,导出之后会有个时间戳。如果当前系统的时间超过了导出的时间戳,导入之后会没有这个key了,因为已过期。

停止再启动memcached,最后导入数据:

[root@node1 ~]# ps aux | grep memcached
root       1962  0.0  0.1 415008  2424 ?        Ssl  09:05   0:00 memcached -u root -d -m 16m -c 8192
root       3661  0.0  0.0 112704   968 pts/1    S+   10:00   0:00 grep --color=auto memcached
[root@node1 ~]# kill 1962
[root@node1 ~]# ps aux | grep memcached
root       3729  0.0  0.0 112704   964 pts/1    S+   10:00   0:00 grep --color=auto memcached
[root@node1 ~]# 
[root@node1 ~]# systemctl start memcached
[root@node1 ~]# nc 127.0.0.1 11211 < data.txt 
STORED
[root@node1 ~]#

OK,导入成功。

查看一下:

[root@node1 ~]# nc 127.0.0.1 11211
get name
VALUE name 1 3
xzm
END

七、php连接memcached

事先已经安装了php,这里使用php7

1、安装php的memcached

下载地址:http://pecl.php.net/package/memcached

[root@node1 ~]# curl -O http://pecl.php.net/get/memcached-3.0.4.tgz
[root@node1 ~]# tar xf memcached-3.0.4.tgz 
[root@node1 ~]# cd memcached-3.0.4
[root@node1 memcached-3.0.4]# /usr/local/php7/bin/phpize 
Configuring for:
PHP Api Version:         20170718
Zend Module Api No:      20170718
Zend Extension Api No:   320170718
[root@node1 memcached-3.0.4]# ./configure --with-php-config=/usr/local/php7/bin/php-config && make && make install
...
checking for libmemcached location... configure: error: memcached support requires libmemcached. Use --with-libmemcached-dir=<DIR> to specify the prefix where libmemcached headers and library are located

报错:需要指定libmemcached目录。

先编译安装libmemcached:

[root@node1 ~]# curl -O https://launchpadlibrarian.net/165454254/libmemcached-1.0.18.tar.gz
[root@node1 ~]# tar xf libmemcached-1.0.18.tar.gz 
[root@node1 ~]# cd libmemcached-1.0.18
[root@node1 libmemcached-1.0.18]# ./configure --prefix=/usr/local/libmemcached --with-memcached && make && make install

重新编译安装php的memcached:

[root@node1 memcached-3.0.4]# ./configure --with-php-config=/usr/local/php7/bin/php-config --with-libmemcached-dir=/usr/local/libm  && make && make install
[root@node1 memcached-3.0.4]# ./configure --with-php-config=/usr/local/php7/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached/  && make && make install

安装成功会提示:

Installing shared extensions:     /usr/local/php7/lib/php/extensions/no-debug-zts-20170718/

2、修改php.ini文件

在php.ini文件中添加一行:extension=memcached.so

[root@node1 ~]# vim /etc/php7/php.ini 
...
extension=memcached.so
...

查看一下php的模块:

[root@node1 ~]# /usr/local/php7/bin/php -m
[PHP Modules]
bcmath
bz2
Core
ctype
curl
date
dom
fileinfo
filter
gd
gettext
hash
iconv
json
ldap
libxml
mbstring
memcached
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
sqlite3
standard
sysvsem
tokenizer
xml
xmlreader
xmlrpc
xmlwriter
zip
zlib
[Zend Modules]

memcached模块已安装成功

八、memcached中存储session

可以在php.ini文件添加:

session.save_handler=memcache

session.save_path="tcp://192.168.10.205:11211"

[root@node1 ~]# vim /etc/php7/php.ini 
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
#session.save_handler = files
session.save_handler = memcache
session.save_path = "tcp://192.168.10.205:11211"

不过这种设置有bug。可以使用下面的设置方法:

在php-fpm.conf对应的pool中添加:

php_value[session.save_handler] = memcache
php_value[session.save_path] = "tcp://192.168.10.205:11211"

php7.x的默认pool在:php-fpm.d/www.conf文件

如果是httpd的可以这样设置:

在httpd的虚拟主机中添加:

php_value  session.save_handler "memcache"
php_value  session.save_path "tcp://192.168.10.205:11211"


发表评论

电子邮件地址不会被公开。 必填项已用*标注