Linux运维学习笔记之二十六:NOSQL之Memcached和Redis

第三十七章 NOSQL之Memcached

一、Memcached概述

Memcached是一个开源的、高性能的内存缓存软件。Mem就是内存,Cache就是缓存的意思。Memcached通过在事先规划好的内存空间中临时缓存数据库中的各类数据,以达到减少业务对数据库的直接高并发访问,从而达到提升数据库的访问性能,加速动态应用服务的能力。

在企业集群架构中应用场景主要是作为数据库的前端缓存应用和集群的session会话共享存储。

查询时先查Memcached,再查数据库,同时更新Memcached。当web程序需要访问后端数据库获取数据时会优先访问Memcached内存缓存,如果缓存中有数据就直接获取返回前端服务及用户,如果没有数据(没有命中),在由程序请求后端的数据库服务器,获取到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到Memcached内存中进行缓存,等待下次请求被访问,Memcache内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高整个网站架构的响应速度,提升了用户体验。

当程序更新、修改或删除数据库中已有的数据时,会同时发送请求通知Memcached已经缓存的同一个ID内容的旧数据失效,从而保证Memcache中数据和数据库中的数据一致。

如果在高并发场合,除了通知Memcached过程的缓存失效外,还会通过相关机制,使得在用户访问新数据前,通过程序预先把更新过的数据推送到memcache中缓存起来,这样可以减少数据库的访问压力,提升Memcached中缓存命中率。

Memcached利用SlabAllocation机制来分配和管理内存。

Slab Allocation机制原理是按照预先规定的大小,将分配给memcached的内存分割成特定长度的内存块(chunk),再把尺寸相同的内存块,分成组(chunksslab class),这些内存块不会释放,可以重复利用。

memcached根据收到的数据的大小,选择最适合数据大小的slab. memcached中保存着slab内空闲chunk的列表,根据该列表选择最适合的chunk, 然后将数据缓存于其中。

Memcached 主要的cache机制是LRU(最近最少用)算法,加上Item过期失效。当存数据到memcached中,可以指定该数据在缓存中可以呆多久Which is forever, orsome time in the future。如果memcached的内存不够用了,过期的slabs会优先被替换,接着就轮到最老的未被使用的slabs。

二、大型站点分布式Memcached缓存的多种应用思路

为了缓解数据库的高并发访问压力,我们可以在数据库层配置数据库读写分离及读数据库做负载均衡,但是更有效更简单的策略是部署Memcache服务作为一个缓存区域,把部分数据库的信息保存在内存中,这样前端的服务能够迅速的读取到原本在数据库中才能读到的数据。那么,最重要的是如何通过Memcached服务分担数据库系统的压力,由于单台Memcached的内存容量有限,也是单点,所以,Memcached也有负载均衡及分布式应用的场景。

1、分布式应用之一:有规律key的封装分发

在应用服务器程序上改造,可以根据key适当进行有规律的封装,进行提取和存放。比如以用户为主的网站,每个用户都有UserID,可以按固定的ID进行存取。存取数据都按照UserID来进行转换。如1开头的用户保存在第1台Memcache服务器上,以2开头的用户保存在第2台Memcache服务器上。

缺点是需要对UserID进行判断,如果业务不一致,或其它类型的应用,就不好适用了。

2、分布式应用之二:根据URL_HASH算法分发

在应用服务器上通过程序及URL_HASH算法去访问Memcache服务,Memcache服务器的地址池可以简单的配在每个程序中。

3、分布式应用之三:中间件代理分发

通过一个中间件代理负责请求后端的Cache服务。如门户网站(百度)

4、分布式应用之四:Cache的负载均衡

可以用常用的LVS,Haproxy做Cache的负载均衡,和普通应用服务相比,这里的重点是轮询算法,Cache服务一般会选择URL_HASH及一致性Hash算法。

三、服务端安装Memcached
1、软件下载地址

Memcached:http://www.danga.com/memcached/

libevent:http://libevent.org/

安装教程:http://instance.iteye.com/blog/1691705

2、安装libevent

tar zxf libevent-1.4.13-stable.tar.gz

cd libevent-1.4.13-stable

./configure

make

make install

3、安装memcached

tar zxf memcached-1.4.13.tar.gz

cd memcached-1.4.13

./configure

make

make install

4、memcached参数

-p <num>:监听的TCP端口(默认:11211)

-U <num>:监听的UDP端口(默认:11211,0表示不监听)

-s <file>:用于监听的UNIX套接字路径(禁用网络支持)

-a <mask>:UNIX套接字访问掩码,八进制数字(默认:0700)

-l <ip_addr>:监听的IP地址。(默认:INADDR_ANY,所有地址)

-d:作为守护进程来运行。

-r:最大核心文件限制。

-u <username>:设定进程所属用户。(只有root用户可以使用这个参数)

-m <num>:所有slabclass可用内存的上限,以MB为单位。(默认:64MB)(译者注:也就是分配给该memcached实例的内存大小。)

-M:内存用光时报错。(不会删除数据)

-c <num>:最大并发连接数。(默认:1024)

-k:锁定所有内存页。注意你可以锁定的内存上限。试图分配更多内存会失败的,所以留意启动守护进程时所用的用户可分配的内存上限。

(不是前面的-u <username>参数;在sh下,使用命令"ulimit-S-lNUM_KB"来设置。)

-v:提示信息(在事件循环中打印错误/警告信息。)

-vv:详细信息(还打印客户端命令/响应)

-vvv:超详细信息(还打印内部状态的变化)

-h:打印这个帮助信息并退出。

-i:打印memcached和libevent的许可。

-P <file>:保存进程ID到指定文件,只有在使用-d选项的时候才有意义。

-f <factor>:不同slabclass里面的chunk大小的增长倍率。(默认:1.25)(译者注:每个slabclass里面有相同数量个slabpage,每个slabpage里面有chunk,且在当前slabclass内的chunk大小固定。而不同slabclass里的chunk大小不一致,具体差异就是根据这个参数的倍率在增长,直到分配的内存用尽。)

-n <bytes>:chunk的最小空间(默认:48)(译者注:chunk数据结构本身需要消耗48个字节,所以一个chunk实际消耗的内存是n+48。)

-L:尝试使用大内存页(如果可用的话)。提高内存页尺寸可以减少"页表缓冲(TLB)"丢失次数,提高运行效率。为了从操作系统获得大内存页,memcached会把全部数据项分配到一个大区块。

-D <char>:使用<char>作为前缀和ID的分隔符。这个用于按前缀获得状态报告。默认是":"(冒号)。如果指定了这个参数,则状态收集会自动开启;如果没指定,则需要用命令"statsdetailon"来开启。

-t <num>:使用的线程数(默认:4)

-R:每个连接可处理的最大请求数。

-C:禁用CAS。

-b:设置后台日志队列的长度(默认:1024)

-B:绑定协议-可能值:ascii,binary,auto(默认)

-I:写每个数据页尺寸。调整数据项最大尺寸。

5、Linux中启动memcached
(1)查看memcached路径

which memcached

/usr/local/bin/memcached

(2)启动单节点memcached

memcached -m 16m -p 11211 -d -u root -c 8192

(3)启动多节点memcached(只需换端口)

memcached -m 16m -p 11212 -d -u root -c 8192

memcached -m 16m -p 11213 -d -u root -c 8192

(4)如果启动报错:找不到libevent-1.4.so.2的错误

a、报错内容

error while loading shared libraries: libevent-1.4.so.2: cannot openshared object file: No such file or directory

b、解决办法

查看libevent-1.4.so.2,将其路径写入etc/ld.so.conf中

find / -name libevent-1.4.so.2

/usr/local/lib/libevent-1.4.so.2

echo "/usr/local/lib" >> /etc/ld.so.conf

c、让配置文件生效

ldconfig

(5)查看memcached

lsof -i :11211

COMMAND     PID USER   FD  TYPE DEVICE SIZE/OFF NODE NAME

memcached 10667 root  26u  IPv4  17394     0t0  TCP *:memcache (LISTEN)

memcached 10667 root  27u  IPv6  17395     0t0  TCP *:memcache (LISTEN)

memcached 10667 root  28u  IPv4  17398     0t0  UDP *:memcache

memcached 10667 root  29u  IPv6  17399     0t0  UDP *:memcache

netstat -lntup | grep mem

tcp    0      0 0.0.0.0:11211        0.0.0.0:*       LISTEN   10667/memcached

tcp    0      0 :::11211              :::*             LISTEN    10667/memcached

udp    0      0 0.0.0.0:11211        0.0.0.0:*                  10667/memcached

udp    0      0 :::11211              :::*                        10667/memcached

6、Windows下启动memcached
(1)手动启动(cmd下)

d:\App_Serv\memcached\memcached.exe -d RunService -l 127.0.0.1 -p11211 -m 500

(2)注册为服务后运行:

sc.exe create Memcached_srv binpath="d:\App_Serv\memcached\memcached.exe-d RunService -p 11211 -m 500" start= auto

7、连接memcached

telnet 127.0.0.1 11211

8、memcached基本操作命令
(1)五种基本 memcached 命令

set、add、replace、get、delete

(2)命令格式           

command <key> <flags> <expiration time><bytes>

<value>

(3)参数    说明

key   用于查找缓存值

flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息

expiration time   在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)

bytes 在缓存中存储的字节点

value 存储的值(始终位于第二行)

(4)示例1:printf方式操作

a、存入数据

printf "set key008 0 0 10\r\noldboy0987\r\n" | nc127.0.0.1 11211

STORED

b、获取数据:无对应key,返回空值

printf "get key007\r\n" | nc 127.0.0.1 11211

END

c、获取对应key的数据

printf "get key008\r\n" | nc 127.0.0.1 11211

VALUE key008 0 10

oldboy0987

END

d、删除对应key的数据

printf "delete key008\r\n" | nc 127.0.0.1 11211  

DELETED

(5)示例1:telnet方式操作

a、telnet连接

telnet 127.0.0.1 11211

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

b、存入数据

set user01 0 0 6

oldboy

STORED

c、获取对应key的数据

get user01

VALUE user01 0 6

oldboy

END

d、删除对应key的数据

delete user01

DELETED

四、客户端安装Memcached
1、下载安装

wget http://pecl.php.net/get/memcache-2.2.5.tgz

tar zxf memcache-2.2.5.tgz

cd memcache-2.2.5

/application/php/bin/phpize

./configure --enable-memcache--with-php-config=/application/php/bin/php-config --with-zlib-dir

make

make install

2、检查memcache.so文件

ls -l /application/php/lib/php/extensions/no-debug-zts-20090626/

-rwxr-xr-x 1 root root 345542 Mar 16 17:21 eaccelerator.so

-rwxr-xr-x 1 root root 839373 Mar 17 18:26 imagick.so

-rwxr-xr-x 1 root root 190162 Mar 17 13:55 memcache.so

-rwxr-xr-x 1 root root 137650 Mar 17 16:03 pdo_mysql.so

-rwxr-xr-x 1 root root 329437 Mar 17 13:20 xcache.so

3、修改php.ini文件

extension_dir = "/application/php5.3.27/lib/php/extensions/no-debug-zts-20090626/"

extension = memcache.so

4、浏览器访问phpinfo

5、编写PHP脚本来操作Memcached
(1)在LAMP服务器上编写PHP脚本

vi /var/html/www/memcachedTest.php

<?php

   $memcache = new Memcache;

   $memcache->connect('127.0.0.1',11211)or die ("Could not connect");

   $memcache->set('key001','Thisis a key001');

   $memcache->set('key002','Thisis a key002');

  

   $get_value01 =$memcache->get('key001');

   $get_value02 =$memcache->get('key002');

   echo$get_value01."<br>";

   echo $get_value02;

?>

(2)直接用PHP程序测试

/application/php/bin/php /var/html/www/memcachedTest.php

This is a key001<br>This is a key002

(3)浏览器访问memcachedTest.php

http://127.0.0.1/memcachedTest.php

This is a key001

This is a key002

五、Memcached的监控
1、登陆Memcached

telnet 127.0.0.1 11211

2、查看系统统计信息

stats

3、查看slabs相关信息

stats slabs

4、查看Items相关信息

stats items

5、查看存在的Item相关信息

stats sizes

6、查看key-value相关信息

stats cachedump

7、清空统计信息

stats reset

第三十八章 NOSQL之Redis

一、Redis概述

redis(Remote DictionaryServer)是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set--有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。[1] 

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

二、Redis优缺点
1、优点

(1)读写性能优异,支持超过100K/每秒的读写频率

(2)支持数据持久化,支持AOF和RDB两种持久化方式

(3)支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

(4)数据结构丰富:除了支持string类型的value外还支持string、hash、set、sortedset、list等数据结构。

(5)所有操作都是原子性的,同时,Redis还支持对几个操作全并后的原子性执行。

2、缺点

(1)Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。

(2)主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。

(3)Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。

(4)Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

三、Redis应用场景
1、MySQL+Memcached架构的问题

实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:

(1)MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。

(2)Memcached与MySQL数据库数据一致性问题。

(3)Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。

(4)跨机房cache同步问题。

2、Redis的最佳应用场景

(1)少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。

(2)作为 Memcached的替代品来使用

(3)当需要除key-value之外的更多数据类型支持时,使用Redis更合适

(4)当存储的数据不能被剔除时,使用Redis更合适

(5)支持持久化

(6)需要负载均衡的场景(Redis的主从同步)

Redis作者谈Redis应用场景http://blog.nosqlfan.com/html/2235.html

3、Redis应用注意事项

(1)要进行Master-Slave配置,出现服务故障时可以支持切换

(2)在Master侧禁用数据持久化,只需在Slave上配置数据持久化

(3)物理内存+虚拟内存不足时,这个时候dump一直死着,时间久了机器会挂掉,这个情况就是灾难

(4)当Redis物理内存超过内存总容量的60%时,就会比较危险了,就开始做swap,内存碎片大

(5)当达到最大内存时,会清空带有过期时间的key,即使key 未到过期时间

(6)Redis和DB同步写的问题,是先写DB,后写Redis,因为写内存基本上是没有问题的

四、Redis服务端安装实战
1、安装Redis
(1)解压安装

tar zxf redis-3.2.6.tar.gz

cd redis-3.2.6

cat README.md

make MALLOC=jemalloc

make PREFIX=/application/redis-3.2.6 install

(2)创建链接文件(去版本号)

ln -s /application/redis-3.2.6/ /application/redis

(3)配置环境变量

echo 'PATH=/application/redis/bin:$PATH' >> /etc/profile

source /etc/profile

which redis-server

/application/redis/bin/redis-server

2、Redis目录说明
(1)目录结构

tree /application/redis

/application/redis

`-- bin

    |-- redis-benchmark

    |-- redis-check-aof

    |-- redis-check-rdb

    |-- redis-cli

    |-- redis-sentinel ->redis-server

    `-- redis-server

(2)命令说明

redis-server:Redis服务器的daemon启动程序

redis-cli:Redis的客户端工具。

redis-benchmark:Redis的性能测试工具

redis-check-aof:更新日志检查 ,加--fix参数为修复log文件

redis-check-rdb:检查本地数据文件

3、生成Redis配置文件

mkdir /application/redis/conf

cp /wddg/tools/redis-3.2.6/redis.conf /application/redis/conf/

4、Redis命令参数说明
(1)redis-server

a、启动并加装指定配置文件

redis-server   /application/redis/conf/redis.conf 

b、查redis服务版本号

redis-server --version

c、查redis帮助

redis-server --help

d、以标准输入作为配置启动redis(其中key为配置参数,value为配置参数值)

redis-server   --port6000   --key value

(2)redis-cli
(3)redis-benchmark

a、参数

-h:设置检测主机 IP 地址,默认为 127.0.0.1 

-p:设置检测主机的端口号,默认为6379 

-s<socket>:服务器套接字 ( 压倒主机和端口 ) 

-c:并发连接数 

-n:请求数 

-d:测试使用的数据集的大小 / 字节的值 ( 默认 3 字节 ) 

-k:1 :表示保持连接 ( 默认值 )0 :重新连接 

-r:SET/GET/INCR 方法使用随机数插入数值

-P:默认为 1( 无管道 ) ,当网络延迟过长时,使用管道方式通信 ( 请求和响应打包发送接收 ) 

-q:简约信息模式,只显示查询和秒值等基本信息。 

--csv:以 CSV 格式输出信息 

-l:无线循环插入测试数据,ctrl+c 停止 

-t<tests>:只运行<tests> 测试逗号分隔的列表命令,如: -tping,set,get 

-I:空闲模式。立即打开 50 个空闲连接和等待。 

b、示例

redis-benchmark --help

redis-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20 

redis-benchmark -t set -n 1000000 -r 100000000 

redis-benchmark -t ping,set,get -n 100000 –csv 

redis-benchmark -r 10000 -n 10000 lpush mylistele:rand:000000000000 

(4)redis-check-aof

redis-check-aof appendonly.aof

(5)redis-check-rdb
五、Redis启动和关闭
1、启动Redis
(1)启动

redis-server /application/redis/conf/redis.conf

(2)出现警告信息

WARNING overcommit_memory is set to 0! Background save may failunder low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctlvm.overcommit_memory=1' for this to take effect.

(3)警告信息原因

内存不足,背景保存失败:Background save may failunder low memory condition.

(4)解决思路

按警告信息提示,需执行sysctl vm.overcommit_memory=1命令,将vm.overcommit_memory设置为1

(5)解决步骤

a、退出Redis

b、执行sysctlvm.overcommit_memory=1

sysctl vm.overcommit_memory=1

vm.overcommit_memory = 1

c、再次启动Redis(加&,后台运行)

redis-server /application/redis/conf/redis.conf &

Server started, Redis version 3.2.6

* DB loaded from disk: 0.001 seconds

* The server is now ready to accept connections on port 6379

2、检查端口

lsof -i :6379

COMMAND    PID USER   FD  TYPE DEVICE SIZE/OFF NODE NAME

redis-ser 5987 root    4u  IPv4 24648      0t0  TCP localhost:6379 (LISTEN)

3、关闭Redis

redis-cli shutdown

User requested shutdown...

* Saving the final RDB snapshot before exiting.

* DB saved on disk

* Removing the pid file.

Redis is now ready to exit, bye bye...

六、Redis客户端操作
1、连接Redis
(1)客户端redis-cli连接

redis-cli -h 127.0.0.1 -p 6379

127.0.0.1:6379>

(2)telnet连接

telnet 127.0.0.1 6379

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

2、查看帮助

help + TAB键可以循环显示命令

127.0.0.1:6379> help GET

  GET key

  summary: Get the value of akey

  since: 1.0.0

  group: string

3、示例
(1)交互方式

127.0.0.1:6379> set no002 redis

OK

127.0.0.1:6379> get no002

"redis"

127.0.0.1:6379> del no001

(integer) 1

127.0.0.1:6379> get no001

(nil)

(2)非交互方式

redis-cli -h 127.0.0.1 -p 6379 set no001 zhangsan

OK

redis-cli -h 127.0.0.1 -p 6379 get no001

"zhangsan"

七、Redis数据类型
1、字符串类型(String)
(1)概要说明

string是redis最基本的类型,是简单的 key-value 键值对,此时,Rdeis相当于一个可以持久化的Memcached服务器

value可以是任何种类的字符串(包括二进制数据),比如jpg图片或者序列化的对象,但长度不能超过1GB。

String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int

(2)相关操作命令

SET key value                  设置key=value

GET key                          或者键key对应的值

GETRANGE key start end         得到字符串的子字符串存放在一个键

GETSET key value                设置键的字符串值,并返回旧值

GETBIT key offset               返回存储在键位值的字符串值的偏移

MGET key1 [key2..]              得到所有的给定键的值

SETBIT key offset value        设置或清除该位在存储在键的字符串值偏移

SETEX key seconds value        键到期时设置值

SETNX key value                  设置键的值,只有当该键不存在

SETRANGE key offset value      覆盖字符串的一部分从指定键的偏移

STRLEN key                        得到存储在键的值的长度

MSET key value [key value...]  设置多个键和多个值

MSETNX key value [key value...] 设置多个键多个值,只有在当没有按键的存在时

PSETEX key milliseconds value  设置键的毫秒值和到期时间

INCR key                            增加键的整数值一次

INCRBY key increment             由给定的数量递增键的整数值

INCRBYFLOAT key increment       由给定的数量递增键的浮点值

DECR key                             递减键一次的整数值

DECRBY key decrement             由给定数目递减键的整数值

APPEND key value                  追加值到一个键

(3)用于管理键的命令

DEL key                        如果存在删除键

DUMP key                       返回存储在指定键的值的序列化版本

EXISTS key                     此命令检查该键是否存在

EXPIRE key seconds             指定键的过期时间

EXPIREAT key timestamp         指定的键过期时间。在这里,时间是在Unix时间戳格式

PEXPIRE key milliseconds       设置键以毫秒为单位到期

PEXPIREAT key milliseconds-timestamp        设置键在Unix时间戳指定为毫秒到期

KEYS pattern                   查找与指定模式匹配的所有键

MOVE key db                    移动键到另一个数据库

PERSIST key                    移除过期的键

PTTL key                       以毫秒为单位获取剩余时间的到期键。

TTL key                        获取键到期的剩余时间。

RANDOMKEY                      从Redis返回随机键

RENAME key newkey               更改键的名称

RENAMENX key newkey            重命名键,如果新的键不存在

TYPE key                       返回存储在键的数据类型的值。

(4)示例:String做计数使用

a、设置初始值

set counter 100

+OK

6008:M 01 May 16:03:01.471 * 1 changes in 900 seconds. Saving...

6008:M 01 May 16:03:01.473 * Background saving started by pid 6125

6125:C 01 May 16:03:01.479 * DB saved on disk   #因为配置参数是设置了自动保存,

6125:C 01 May 16:03:01.481 * RDB: 0 MB of memory used bycopy-on-write

6008:M 01 May 16:03:01.573 * Background saving terminated withsuccess

b、增加计数

incr counter

:101

incr counter

:102

2、列表类型(List)
(1)概要说明

Redis列表是简单的字符串列表,可以类比到C++中的std::list,简单的说就是一个链表或者说是一个队列。可以从头部或尾部向Redis列表添加元素。列表的最大长度为2^32 - 1,也即每个列表支持超过40亿个元素。

Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表、粉丝列表等都可以用Redis的list结构来实现,再比如有的应用使用Redis的list类型实现一个简单的轻量级消息队列,生产者push,消费者pop/bpop。

(2)相关操作命令

BLPOP key1 [key2 ] timeout:取出并获取列表中的第一个元素,或阻塞,直到有可用

BRPOP key1 [key2 ] timeout:取出并获取列表中的最后一个元素,或阻塞,直到有可用

BRPOPLPUSH source destination timeout:从列表中弹出一个值推到另一个列表并返回它;或阻塞,直到有可用

LINDEX key index:从一个列表其索引获取对应的元素

LINSERT key BEFORE|AFTER pivot value:在列表中的其他元素之后或之前插入一个元素

LLEN key:获取列表的长度

LPOP key:获取并取出列表中的第一个元素

LPUSH key value1 [value2] :在前面加上一个或多个值的列表

LPUSHX key value:在前面加上一个值列表,仅当列表中存在

LRANGE key start stop:从一个列表获取各种元素

LREM key count value:从列表中删除元素

LSET key index value:在列表中的索引设置一个元素的值

LTRIM key start stop:修剪列表到指定的范围内

RPOP key:取出并获取列表中的最后一个元素

RPOPLPUSH source destination:删除最后一个元素的列表,将其附加到另一个列表并返回它

RPUSH key value1 [value2] :添加一个或多个值到列表

RPUSHX key value:添加一个值列表,仅当列表中存在

(3)示例:

redis 127.0.0.1:6379> lpush list1 redis

(integer) 1

redis 127.0.0.1:6379> lpush list1 hello

(integer) 2

redis 127.0.0.1:6379> rpush list1 world

(integer) 3

redis 127.0.0.1:6379> llen list1

(integer) 3

redis 127.0.0.1:6379> lrange list1 0 3

1) "hello"

2) "redis"

3) "world"

redis 127.0.0.1:6379> lpop list1

"hello"

redis 127.0.0.1:6379> rpop list1

"world"

redis 127.0.0.1:6379> lrange list1 0 3

1) "redis"

3、HASH类型(Hash)
(1)概要说明

类似C#中的dict类型或者C++中的hash_map类型。

Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

假设有多个用户及对应的用户信息,可以用来存储以用户ID为key,将用户信息序列化为比如json格式做为value进行保存。

(2)相关操作命令

HDEL key field[field...]:删除对象的一个或几个属性域,不存在的属性将被忽略

HEXISTS key field:查看对象是否存在该属性域

HGET key field:获取对象中该field属性域的值

HGETALL key:获取对象的所有属性域和值

HINCRBY key field value:将该对象中指定域的值增加给定的value,原子自增操作,只有integer值可以使用

HINCRBYFLOAT key field increment:将该对象中指定域的值增加给定的浮点数

HKEYS key:获取对象的所有属性字段

HVALS key:获取对象的所有属性值

HLEN key:获取对象的所有属性字段的总数

HMGET key field[field...]:获取对象的一个或多个指定字段的值

HSET key field value:设置对象指定字段的值

HMSET key field value [field value ...]:同时设置对象中一个或多个字段的值

HSETNX key field value:只在对象不存在指定的字段时才设置字段的值

HSTRLEN key field:返回对象指定field的value的字符串长度,如果该对象或者field不存在,返回0.

HSCAN key cursor [MATCH pattern] [COUNTcount]:类似SCAN命令

(3)示例:

127.0.0.1:6379> hset person name jack

(integer) 1

127.0.0.1:6379> hset person age 20

(integer) 1

127.0.0.1:6379> hset person sex famale

(integer) 1

127.0.0.1:6379> hgetall person

1) "name"

2) "jack"

3) "age"

4) "20"

5) "sex"

6) "famale"

127.0.0.1:6379> hkeys person

1) "name"

2) "age"

3) "sex"

127.0.0.1:6379> hvals person

1) "jack"

2) "20"

3) "famale"

4、集合类型(Set)
(1)概要说明

可以理解为一堆值不重复的列表,类似数学领域中的集合概念,且Redis也提供了针对集合的求交集、并集、差集等操作。

set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。又或者在微博应用中,每个用户关注的人存在一个集合中,就很容易实现求两个人的共同好友功能。

(2)相关操作命令

SADD key member [member ...]:添加一个或者多个元素到集合(set)里  

SCARD key:获取集合里面的元素数量                                

SDIFF key [key ...]:获得队列不存在的元素                        

SDIFFSTORE destination key [key ...]:获得队列不存在的元素,并存储

SINTER key [key ...]:获得两个集合的交集                         

SINTERSTORE destination key [key ...]:获得两个集合的交集,并存储?

SISMEMBER key member:确定一个给定的值是一个集合的成员           

SMEMBERS key:获取集合里面的所有key                              

SMOVE source destination member:移动集合里面的一个key到另一个集合

SPOP key [count]:获取并删除一个集合里面的元素                   

SRANDMEMBER key [count]:从集合里面随机获取一个元素              

SREM key member [member ...]:从集合里删除一个或多个元素,不存在的

SUNION key [key ...]:添加多个set元素                            

SUNIONSTORE destination key [key ...]:合并set元素,并将结果存入新

SSCAN key cursor [MATCH pattern] [COUNT count]:迭代set里面的元素

(3)示例:

redis> SADD myset "Hello"

(integer) 1

redis> SADD myset "World"

(integer) 1

redis> SMEMBERS myset

1) "World"

2) "Hello"

redis> SADD myset "one"

(integer) 1

redis> SISMEMBER myset "one"

(integer) 1

redis> SISMEMBER myset "two"

(integer) 0

5、有序集合类型(Sorted Set)
(1)概要说明

Redis有序集合类似Redis集合,不同的是增加了一个功能,即集合是有序的。一个有序集合的每个成员带有分数,用于进行排序。

Redis有序集合添加、删除和测试的时间复杂度均为O(1)(固定时间,无论里面包含的元素集合的数量)。列表的最大长度为2^32- 1元素(4294967295,超过40亿每个元素的集合)。

Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的publictimeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

又比如用户的积分排行榜需求就可以通过有序集合实现。还有上面介绍的使用List实现轻量级的消息队列,其实也可以通过Sorted Set实现有优先级或按权重的队列。

(2)相关操作命令

ZADD key score1 member1 [score2 member2]:添加一个或多个成员到有序集合,或者如果它已经存在更新其分数

ZCARD key:得到的有序集合成员的数量

ZCOUNT key min max:计算一个有序集合成员与给定值范围内的分数

ZINCRBY key increment member:在有序集合增加成员的分数

ZINTERSTORE destination numkeys key [key...]:多重交叉排序集合,并存储生成一个新的键有序集合。

ZLEXCOUNT key min max:计算一个给定的字典范围之间的有序集合成员的数量

ZRANGE key start stop [WITHSCORES]:由索引返回一个成员范围的有序集合(从低到高)

ZRANGEBYLEX key min max [LIMIT offsetcount]:返回一个成员范围的有序集合(由字典范围)

ZRANGEBYSCORE key min max [WITHSCORES][LIMIT]:返回有序集key中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员,有序集成员按 score 值递增(从小到大)次序排列

ZRANK key member:确定成员的索引中有序集合

ZREM key member [member ...]:从有序集合中删除一个或多个成员,不存在的成员将被忽略

ZREMRANGEBYLEX key min max:删除所有成员在给定的字典范围之间的有序集合

ZREMRANGEBYRANK key start stop:在给定的索引之内删除所有成员的有序集合

ZREMRANGEBYSCORE key min max:在给定的分数之内删除所有成员的有序集合

ZREVRANGE key start stop [WITHSCORES]:返回一个成员范围的有序集合,通过索引,以分数排序,从高分到低分

ZREVRANGEBYSCORE key max min [WITHSCORES]:返回一个成员范围的有序集合,以socre排序从高到低

ZREVRANK key member:确定一个有序集合成员的索引,以分数排序,从高分到低分

ZSCORE key member:获取给定成员相关联的分数在一个有序集合

ZUNIONSTORE destination numkeys key [key...]:添加多个集排序,所得排序集合存储在一个新的键

ZSCAN key cursor [MATCH pattern] [COUNTcount]:增量迭代排序元素集和相关的分数

(3)示例:

redis 127.0.0.1:6379> zadd dbs 100 redis

(integer) 1

redis 127.0.0.1:6379> zadd dbs 98 memcached

(integer) 1

redis 127.0.0.1:6379> zadd dbs 99 mongodb

(integer) 1

redis 127.0.0.1:6379> zadd dbs 99 leveldb

(integer) 1

redis 127.0.0.1:6379> zcard dbs

(integer) 4

redis 127.0.0.1:6379> zcount dbs 10 99

(integer) 3

redis 127.0.0.1:6379> zrank dbs leveldb

(integer) 1

redis 127.0.0.1:6379> zrank dbs other

(nil)

redis 127.0.0.1:6379> zrangebyscore dbs 98 100

1) "memcached"

2) "leveldb"

3) "mongodb"

4) "redis"

八、Redis的PHP客户端安装
1、解压安装

wget https://github.com/nicolasff/phpredis/archive/master.zip

unzip master.zip

cd phpredis-master/

/application/php/bin/phpize

./configure -with-php-config=/application/php/bin/php-config

make

make install

2、查看安装结果

ll /application/php5.3.27/lib/php/extensions/no-debug-zts-20090626/

-rwxr-xr-x 1 root root  345542Mar 16 17:21 eaccelerator.so

-rwxr-xr-x 1 root root  839373Mar 17 18:26 imagick.so

-rwxr-xr-x 1 root root  190162Mar 17 13:55 memcache.so

-rwxr-xr-x 1 root root  137650Mar 17 16:03 pdo_mysql.so

-rwxr-xr-x 1 root root 1166392 May 1 17:06 redis.so

-rwxr-xr-x 1 root root  329437Mar 17 13:20 xcache.so

3、将redis.so加入php.ini文件中

echo "extension = redis.so" >>/application/php/lib/php.ini

tail -1 /application/php/lib/php.ini

extension = redis.so

4、重启/重新加载php
(1)LNMP

killall php-fpm

/application/php/sbin/php-fpm

(2)LAMP

/application/apache/bin/apachectl graceful

5、通过phpinfo查看是否加载redis

http://127.0.0.1/phpinfo.php

九、Redis配置文件说明
1、查看Redis配置文件redis.conf的内容

cat -n /application/redis/conf/redis.conf

2、第128行:daemonize no

只有是yes时,才会是daemon进程,默认是no

3、第150行:pidfile

pidfile /var/run/redis_6379.pid

4、第158行:loglevel notice

日志级别最好不要用notice,用warning

5、第180行到248行:数据自动保存

格式:save <seconds> <changes>

190  #   after 900 sec (15 min) if at least 1 keychanged

191  #   after 300 sec (5 min) if at least 10 keyschanged

192  #   after 60 sec if at least 10000 keys changed

 

202  save 900 1

203  save 300 10

204  save 60 10000

6、第249行到466行:主从同步
(1)只需在从库配置,主库不用管

265  # slaveof<masterip> <masterport>

272  # masterauth<master-password>   #如果有密码

(2)测试(在从库配置)

slaveof 192.168.1.2 6379

(3)在从库打开监控,查看同步信息

redis-cli -h localhost -p 6379 monitor

十、Redis统计信息说明
1、命令

127.0.0.1:6379> info

2、格式

help info

INFO [section]

summary: Get information and statistics about the server

since: 1.0.0

group: server

127.0.0.1:6379> info

127.0.0.1:6379> info server

3、说明
(1)server:一般Redis服务器信息,包含以下域:

redis_version:Redis服务器版本

redis_git_sha1:GitSHA1

redis_git_dirty:Gitdirtyflag

os:Redis服务器的宿主操作系统

arch_bits:架构(32或64位)

multiplexing_api:Redis所使用的事件处理机制

gcc_version:编译Redis时所使用的GCC版本

process_id:服务器进程的PID

run_id:Redis服务器的随机标识符(用于Sentinel和集群)

tcp_port:TCP/IP监听端口

uptime_in_seconds:自Redis服务器启动以来,经过的秒数

uptime_in_days:自Redis服务器启动以来,经过的天数

lru_clock:以分钟为单位进行自增的时钟,用于LRU管理

(2)clients:已连接客户端信息,包含以下域:

connected_clients:已连接客户端的数量(不包括通过从属服务器连接的客户端)

client_longest_output_list:当前连接的客户端当中,最长的输出列表

client_longest_input_buf:当前连接的客户端当中,最大输入缓存

blocked_clients:正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量

(3)memory:内存信息,包含以下域:

used_memory:由Redis分配器分配的内存总量,以字节(byte)为单位

used_memory_human:以人类可读的格式返回Redis分配的内存总量

used_memory_rss:从操作系统的角度,返回Redis已分配的内存总量(俗称常驻集大小)。这个值和top、ps等命令的输出一致。

used_memory_peak:Redis的内存消耗峰值(以字节为单位)

used_memory_peak_human:以人类可读的格式返回Redis的内存消耗峰值

used_memory_lua:Lua引擎所使用的内存大小(以字节为单位)

mem_fragmentation_ratio:used_memory_rss和used_memory之间的比率

mem_allocator:在编译时指定的,Redis所使用的内存分配器。可以是libc、jemalloc或者tcmalloc。

在理想情况下,used_memory_rss的值应该只比used_memory稍微高一点儿。

当rss>used,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。

内存碎片的比率可以通过mem_fragmentation_ratio的值看出。

当used>rss时,表示Redis的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。

BecauseRedisdoesnothavecontroloverhowitsallocationsaremappedtomemorypages,highused_memory_rssisoftentheresultofaspikeinmemoryusage.

当Redis释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。

如果Redis释放了内存,却没有将内存返还给操作系统,那么used_memory的值可能和操作系统显示的Redis内存占用并不一致。

查看used_memory_peak的值可以验证这种情况是否发生。

(4)其它统计信息

persistence:RDB和AOF的相关信息

stats:一般统计信息

replication:主/从复制信息

cpu:CPU计算量统计信息

commandstats:Redis命令统计信息

cluster:Redis集群信息

keyspace:数据库相关的统计信息

all:返回所有信息

default:返回默认选择的信息

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值