21.9 redis介绍

一、介绍 redis 是一个开源的、使用C语言编写的、支持网络交互的、可以基于内存也可以持久化的Key-Value数据库。 redis的源码非常简单,只要有时间看看谭浩强的C语言,在去看redis的源码能看懂50-60%。 redis目前最大的集群应该是新浪的应该。 redis目前是vmvaer来支持的,很多的开源软件都需要某些组织来支持的。如果一个开源软件没有金钱来支持的话很难走的持久

二、Redis和Memcache对比

持久化:以电商举例,session用memcache来做的,购物车用redis来做的,当你退出的时候会提示你购物车里的物品会在你退出后继续保存。相对来说memcache存储更单一化! 主从复制:redis的主从复制类似mysql的主从复制但是原理是不同的! 虚拟内存:说白了就是把内存里一些不用的东西放在硬盘上,最好不要用,降低效率,现在内存来说比较便宜。

21.10 redis安装

cd /usr/local/src/
wget http://download.redis.io/releases/redis-4.0.1.tar.gz
tar zxvf redis-4.0.1.tar.gz
cd redis-4.0.1
make && make install
cp redis.conf /etc/redis.conf

如果安装时报错:

zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录

解决方案:

执行命令:make MALLOC=libc&&make install

vim /etc/redis.conf #修改如下配置 #把

daemonize no
#改成
daemonize yes
#no前台启动,yes后台启动
logfile "/var/log/redis.log"     #定义日志文件
dir /data/redis/             #redis文件存放路径
appendonly yes                   #开启aof,aof名字:apendonly.aof

创建上面指定的dir

mkdir /data/redis`

两项内核参数,没必要修改时保持默认 在rc.local添加此两项参数,开启时可以启动

sysctl vm.overcommit_memory=1
echo never > /sys/kernel/mm/transparent_hugepage/enabled

启动Redis服务

redis-server /etc/redis.conf`

检查进程

ps aux |grep redis
root       2233  0.0  0.2 141952  2212 ?        Ssl  10:00   0:30 redis-server 127.0.0.1:6379
root      11624  0.0  0.0 112720   968 pts/0    S+   20:44   0:00 grep --color=auto redis

21.11 redis持久化

数据存放在内存里,无论是读和写都是非常快的,但是如果重启服务器或者重启服务,数据都会因此丢失。所以,数据较为重要的话,需要实施数据持久化。 Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File) RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上。#简单来说,就是把内存的数据做一个镜像,然后完整映射存储到磁盘上面。 存储方式是通过redis.conf的save参数来定义存储方式。 配置文件有以下字段

缓存设置:配置文件中save选项 
save 900 1 # 900秒内有至少1个键被更改则进行快照 
save 300 10 # 300秒内有至少10个键被更改则进行快照 
save 60 10000 # 60秒内有至少10000个键被更改则进行快照

满足这3个条件则会触发持久化存储 如果把持久化关闭,则把save参数条件都deleted,然后把#save "" 注释去掉,改成这样 save "" AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。#数据随着操作时间的增长而增长。 其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。 AOF有三种方式,也是在配置文件redis.conf中定义的

appendfsync always#一直写,每次变更就写
appendfsync everysec		    #每秒写
appendfsync no#每隔一段时间写,最不安全的

如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。 两者对比,AOF保存比较存储比较安全

21.12 redis数据类型

Redis数据类型-string

string为最简单的类型,与Memcached一样的类型,一个key对应一个value,其支持的操作与Memcached的操作类似,它的功能更丰富。设置可以存二进制的对象。

示例:

# redis-cli #连接redis的命令,redis通用入口命令 set设置单个key-value get单个值

127.0.0.1:6379> set key1 10
OK
127.0.0.1:6379> get key1
"10"
#mset设置多个key-value
#mget多个值
127.0.0.1:6379> mset key2 20 key3 30
OK
127.0.0.1:6379> mget key1 key2 key3
1) "10"
2) "20"
3) "30"

**Redis数据类型-list **

list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。

使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。

list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行。

push与pop的是推挤特性,push将k-v推进list,然后pop把值排出来

 127.0.0.1:6379> LPUSH list1 111
(integer) 1
127.0.0.1:6379> LPUSH list1 222
(integer) 2
127.0.0.1:6379> LPUSH list1 333
(integer) 3
#LRANGE查值,0 -1表示倒序
127.0.0.1:6379> LRANGE list1 0 -1
1) "333"
2) "222"
3) "111"
#LPOP取值,取值后,list会缺少被取出的值
127.0.0.1:6379> LPOP list1
"333"
127.0.0.1:6379> LRANGE list1 0 -1
1) "222"
2) "111"

Redis数据类型-set set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。 set示例

 #SADD
127.0.0.1:6379> SADD set1 1
(integer) 1
127.0.0.1:6379> SADD set1 2
(integer) 1
127.0.0.1:6379> SADD set1 3
(integer) 1
127.0.0.1:6379> SADD set1 a
(integer) 1
127.0.0.1:6379> SADD set1 b
(integer) 1
127.0.0.1:6379> SADD set2 2
(integer) 1
127.0.0.1:6379> SADD set2 3
(integer) 1
127.0.0.1:6379> SADD set2 4
(integer) 1
127.0.0.1:6379> SADD set2 a
(integer) 1
127.0.0.1:6379> SADD set2 b
(integer) 1
#SMEMBERS 查key值
127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "a"
3) "3"
4) "2"
5) "b"
#SMEMBERS 查key值
127.0.0.1:6379> SMEMBERS set2
1) "a"
2) "4"
3) "3"
4) "2"
5) "b"
#SINTER 求交集
127.0.0.1:6379> SINTER set1 set2
1) "a"
2) "3"
3) "2"
4) "b"
#SUNION 去重,并集
127.0.0.1:6379> SUNION set1 set2
1) "1"
2) "a"
3) "2"
4) "b"
5) "4"
6) "3"
#SDIFF 求差集
127.0.0.1:6379> SDIFF set1 set2
1) "1"
#SREM 删除元素
127.0.0.1:6379> SREM set1 1
(integer) 1
127.0.0.1:6379> SMEMBERS set1
1) "a"
2) "3"
3) "2"
4) "b"

解释:

127.0.0.1:6379> SINTER set1 set2 //交集,相同的交集一起

127.0.0.1:6379> SUNION set1 set2 //并集,set1,set2去重合并

127.0.0.1:6379> SDIFF set1 set2 //差集,不同的元素

127.0.0.1:6379> SREM set1 c //删除元素

127.0.0.1:6379> SADD set2 a 2  b

**Redis数据类型-sort set **

sorted set是有序集合,它比set多了一个权重参数score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的 Sorted Sets,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。

127.0.0.1:6379> ZADD set3 10 a
(integer) 1
127.0.0.1:6379> ZADD set3 20 "a-2"
(integer) 1
127.0.0.1:6379> ZADD set3 30 b
(integer) 1
127.0.0.1:6379> ZADD set3 40 b-2
(integer) 1
#顺序
127.0.0.1:6379> ZRANGE set3 0 -1
1) "a"
2) "a-2"
3) "b"
4) "b-2"
#倒序
127.0.0.1:6379> ZREVRANGE set3 0 -1
1) "b-2"
2) "b"
3) "a-2"
4) "a"

##排序的时候,score值不会被显示出来的 Redis数据类型-hash 在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。 示例 格式: #HSET key value(多个元素)

127.0.0.1:6379> HSET hash1 name luo
(integer) 1
127.0.0.1:6379> HSET hash1 age 28
(integer) 1
127.0.0.1:6379> HSET hash1 job IT
(integer) 1
#HGET key value
127.0.0.1:6379> HGET hash1 name
"luo"
127.0.0.1:6379> HGET hash1 job
"IT"
127.0.0.1:6379> HGET hash1 age
"28"
#HGETALL 获取全部hash value
127.0.0.1:6379> HGETALL hash1
1) "name"
2) "luo"
3) "age"
4) "28"
5) "job"
6) "IT"

21.13/21.14/21.15 redis常用操作

** Redis常用操作 (string, list)**

set key1 aminglinux
get key1
set key1 aming//第二次赋值会覆盖
setnx key2 aaa //返回1 如果key2不存在直接创建key
setnx key2 bbb  //返回0,如果key2存在,返回0
setex key3 10 1 //给key3设置过期时间为10s,值为1,若key已经存在,会覆盖新的值
mset k1 1 k2 a k3 c
mget k1 k3 k2
lpush lista a //从左侧加入一个元素
lpush lista b
lrange lista 0 -1 
lpop lista //从左侧取出第一个元素
rpush lista 1 //从右侧加入一个元素
rpop lista //从右侧取出第一个元素

string

 #set,get用法
 set key1 aminglinux
 get key1
 #set第二次被覆盖
 set key1 aming//第二次赋值会覆盖
 #setnx 检查key值是否存在,key存在,则不被覆盖,key不存在,直接创建key
 127.0.0.1:6379> get key1
"10"
127.0.0.1:6379> get key10
(nil)
 127.0.0.1:6379> SETNX key1 100
(integer) 0
127.0.0.1:6379> SETNX key10 100
(integer) 1
#设置过期时间,
格式:set `key` `value` ex `time`
127.0.0.1:6379> set key11 111 ex 10
OK
#setex用法,给key11设置过期时间为10s,值为1,若key已经存在,会覆盖新的值
格式: SETEX `key` `seconds` `value`
127.0.0.1:6379> SETEX key11 1000 11
OK
127.0.0.1:6379> get key11
"11"
list
127.0.0.1:6379> LPUSH list11 aaa
(integer) 1
127.0.0.1:6379> LPUSH list11 bbb
(integer) 2
127.0.0.1:6379> LPUSH list11 ccc
(integer) 3
127.0.0.1:6379> LRANGE list11 0 -1
1) "ccc"
2) "bbb"
3) "aaa"
#从左侧取出第一个元素 ,最上的一个元素
127.0.0.1:6379> LPOP list11
"ccc"
#从右侧取出第一个元素,最下的一个元素
127.0.0.1:6379> RPOP list11
"aaa"
#取出的value,不会再存在list里面
127.0.0.1:6379> LRANGE list11 0 -1
1) "bbb"

Redis常用操作(list, set)

 linsert  lista  before  2 3  //在2的前面插入一个元素为3
 lset lista 4 bbb  //把第5个元素修改为bbb
 lindex lista 0  //查看第1个元素
 lindex lista 3  //查看第4个元素
 llen lista  //查看链表中有几个元素
 sadd seta aaa  //向集合seta中放入元素
 smembers seta   //查看集合中的所有元素 
 srem  seta    aaa //删除元素 
 spop  seta    //随机取出一个元素,删除
 sdiff  seta  setb   //求差集,以seta为标准
 sdiffstore setc seta setb   //求差集并且存储,存储到了setc里 
 sinter seta setb    //求交集
 sinterstore  setd seta setb  //将交集存储setd 
 sunion seta setb  //求并集
 sunionstore sete seta setb   //求并集并存储到sete
#在xxx的前面插入一个元素为xxx
127.0.0.1:6379> LRANGE list11 0 -1
1) "bbb"
127.0.0.1:6379> LINSERT list11 before bbb aaa
(integer) 2
127.0.0.1:6379> LRANGE list11 0 -1
1) "aaa"
2) "bbb"
#在xxx的后面插入一个元素为xxx
127.0.0.1:6379> LINSERT list11 after bbb ccc
(integer) 3
127.0.0.1:6379> LRANGE list11 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
#把第1个元素修改为123 ,用下标表示,0=no.1,1=no.2,以此类推
格式 LET `key` `位置` `value`
127.0.0.1:6379> LSET list11 0 123
OK
127.0.0.1:6379> LRANGE list11 0 -1
1) "123"
2) "bbb"
3) "ccc"
#查看第一个元素
127.0.0.1:6379> LRANGE list11 0 -1
1) "123"
2) "bbb"
3) "ccc"
127.0.0.1:6379> LINDEX list11 0
"123"
#查看链表中有几个元素
LLEN list11
#随机取出一个元素,删除
127.0.0.1:6379> sadd seta aaa
(integer) 1
127.0.0.1:6379> sadd seta bbb
(integer) 1
127.0.0.1:6379> SPOP seta
"aaa"
127.0.0.1:6379> SMEMBERS seta
1) "bbb"

Redis常用操作(set, zset)

sismember seta aaa  //判断一个元素是否属于一个集合
srandmember  seta  //随机取出一个元素,但不删除
zadd zseta 11 123 //创建有序集合
zrange zseta 0 -1   //显示所有元素,按顺序显示
zrange zseta 0 -1 withscores   //可以带上分值
zrem zseta 222  //删除指定元素
zrank zseta  222  //返回元素的索引值,索引值从0开始,按score正向排序
zrevrank zseta 222   //同上,不同的是,按score反序排序
zrevrange  zseta  0 -1  反序显示所有元素,并带分值
zcard zseta  //返回集合中所有元素的个数
zcount  zseta 1 10  //  返回分值范围1-10的元素个数
zrangebyscore  zseta 1 10 // 返回分值范围1-10的元素
zremrangebyrank zseta  0 2  //删除索引范围0-2的元素,按score正向排序
zremrangebyscore zseta  1 10 //删除分值范围1-10的元素
#创建有序集合
 127.0.0.1:6379> ZADD zseta 11 123
(integer) 1
127.0.0.1:6379> ZADD zseta 22 223
(integer) 1
127.0.0.1:6379> ZRANGE zseta 0 -1
1) "123"
2) "223"
#删除指定元素
127.0.0.1:6379> ZREM zseta 123
(integer) 1
127.0.0.1:6379> ZREM zseta 223
(integer) 1
#返回元素的索引值,索引值(integer后面的值)从0开始,按score正向排序,
127.0.0.1:6379> ZADD zseta 10 aaa
(integer) 1
127.0.0.1:6379> ZADD zseta 30 cccc
(integer) 1
127.0.0.1:6379> ZADD zseta 20 bbb
(integer) 1
127.0.0.1:6379> ZRANGE zseta 0 -1
1) "aaa"
2) "bbb"
3) "cccc"
127.0.0.1:6379> ZRANk zseta aaa
(integer) 0
127.0.0.1:6379> ZRANk zseta ccc
(nil)
127.0.0.1:6379> ZRANk zseta cccc
(integer) 2
#反序排序
127.0.0.1:6379> ZREVRANGE zseta 0 -1
1) "cccc"
2) "bbb"
3) "aaa"

**Redis常用操作(hash) **

 hset user1  name aming  //建立hash
 hset user1 age 30 
 hset user1 job  it
 hgetall user1
 hmset user2  name aming age 30  job it    //批量建立键值对
 hmget user2
 hmget user2 name age  job
 hdel user2 job   //删除指定filed
 hkeys user2   //打印所有的key
 hvals user2  //打印所有的values
 hlen user2  //查看hash有几个filed

21.16 redis操作键值

查看redis的键值,支持模糊匹配,例如:#key k*

127.0.0.1:6379> keys *
1) "h1"
2) "key"
3) "list1"
4) "key2"
5) "key3"
6) "zseta"
7) "11"
8) "set1"
9) "key1"
10) "set2"
11) "set3"

keys * //取出所有key keys my* //模糊匹配 exists name //有name键 返回1 ,否则返回0; del key1 // 删除一个key //成功返回1 ,否则返回0; EXPIRE key1 100 //设置key1 100s后过期 ttl key // 查看键 还有多长时间过期,单位是s,当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,返回 key 的剩余生存时间。 select 0 //代表选择当前数据库,默认进入0 数据库 move age 1 // 把age 移动到1 数据库 示例:

127.0.0.1:6379> SMEMBERS set2
1) "3"
2) "2"
3) "4"
4) "c"
5) "b"
6) "5"
127.0.0.1:6379> MOVE set2 1
(integer) 1
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> keys *
1) "set2"

persist key1 //取消key1的过期时间 示例:

127.0.0.1:6379> EXPIRE 11 1000
(integer) 1
127.0.0.1:6379> TTL 11
(integer) 996
127.0.0.1:6379> PERSIST 11
(integer) 1
127.0.0.1:6379> TTL 11
(integer) -1
#key值存在,但是没有过期时间

randomkey //随机返回一个key

127.0.0.1:6379> RANDOMKEY
"key3"
127.0.0.1:6379> RANDOMKEY
"set1"
127.0.0.1:6379> RANDOMKEY
"set3"
127.0.0.1:6379> RANDOMKEY
"set1"

rename oldname newname //重命名key

127.0.0.1:6379> RENAME 11 key11
OK
127.0.0.1:6379> keys key11
1) "key11"

type key1 //返回键的类型
示例:

127.0.0.1:6379> TYPE h1
hash
127.0.0.1:6379> TYPE key11
string
127.0.0.1:6379> TYPE set3
zset

Redis常用操作(服务)

dbsize //返回当前数据库中key的数目

127.0.0.1:6379> keys *
1) "key11"
2) "h1"
3) "key"
4) "list1"
5) "key2"
6) "key3"
7) "zseta"
8) "set1"
9) "key1"
10) "set3"
127.0.0.1:6379> DBSIZE
(integer) 10

info //返回redis数据库状态信息 flushdb //清空当前数据库中所有的键

127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> keys *
1) "set2"
127.0.0.1:6379[1]> FLUSHDB
OK
127.0.0.1:6379[1]> keys *
(empty list or set)

flushall //清空所有数据库中的所有的key bgsave //保存数据到 rdb文件中,在后台运行 适用环境:内存写入redis数据量庞大,需要迁移到后台rdb文件操作。 响应速度:取决于数据量的多少。 save //作用同上,但是在前台运行 操作环境:当前窗口

config get * //获取所有配置参数

127.0.0.1:6379[1]> CONFIG GET *
.
.
.
164) ""
165) "notify-keyspace-events"
166) ""
167) "bind"
168) "127.0.0.1"

config get dir //获取配置参数

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"
127.0.0.1:6379> CONFIG GET bind
1) "bind"
2) "127.0.0.1"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
config set dir  //更改配置参数
127.0.0.1:6379> CONFIG SET timeout 100
OK
127.0.0.1:6379> CONFIG GET timeout
1) "timeout"
2) "100"

数据恢复: 首先定义或者确定dir目录和dbfilename,然后把备份的rdb文件放到dir目录下面,重启redis服务即可恢复数据

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
#dump.rdb的名字可以自定义更改

21.17 redis安全设置

iptables设置对6379端口的保护,以免涉外操控。

设置监听ip,在配置文件redis.conf中定义

bind 127.0.0.1  2.2.2.2`
#可以是多个ip,用空格分隔

(如果不设置这个配置,默认监听所有,公网ip,内网ip。。。) 设置监听端口

port 16000

设置密码

修改参数(如果无该参数,手动追加)

格式:requirepass 密码

vim /etc/redis.conf
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes
requirepass luolinux>aaa  

#添加requirepass参数定义登录密码 修改参数后,重启redis服务并连接redis数据库

killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

登录命令:

# redis-cli -a 'luolinux>aaa'`
127.0.0.1:6379> keys *
1) "key11"
2) "h1"
3) "key"
4) "list1"
5) "key2"
6) "key3"
7) "zseta"
8) "set1"
9) "key1"
10) "set3"

将config命令改名

config命令在redis的效果

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"

这是修改前的效果,config能获取很多数据,如果×××***会获取核心数据内容。

修改参数(如果无该参数,手动追加): rename-command CONFIG aming

vim /etc/redis.conf
# security of read only slaves using 'rename-command' to shadow all the
# administrative / dangerous commands.
slave-read-only yes
rename-command CONFIG aming
#添加参数,修改config的命令符为"aming",意思就是键入aming相当于键入config的效果
修改参数后,重启redis服务并连接redis数据库
killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

可以看到"aming"命令已经生效

127.0.0.1:6379> aming get dir
1) "dir"
2) "/data/redis"
而"config"命令已经失效
127.0.0.1:6379> CONFIG GET dir
(error) ERR unknown command 'CONFIG'

禁掉config命令

#把“”引用部分的内容改空即可

rename-command CONFIG “”`

21.18 redis慢查询日志

开启慢查询日志功能

编辑配置文件/etc/redis.conf

vim /etc/redis.conf
slowlog-log-slower-than 10000
slowlog-max-len 128

解释:

针对慢查询日志,可以设置两个参数,一个是执行时长,单位是微秒,另一个是慢查询日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。

slowlog-log-slower-than 1000
#单位ms,表示慢于1000ms则记录日志
slowlog-max-len 128
#定义日志长度,表示最多存128条

修改慢查询的参数为10ms进行测试(其实正常执行的命令都>10ms)

slowlog-log-slower-than 10000
改成
slowlog-log-slower-than 10

修改后重启redis

killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

键入任意执行命令进行测试

127.0.0.1:6379> SLOWLOG get
1)  1) (integer) 0
   2) (integer) 1534932088
   3) (integer) 1035
   4) 1) "COMMAND"
   5) "127.0.0.1:44242"
   6) ""
127.0.0.1:6379> keys *
1) "key2"
2) "key11"
3) "key1"
4) "h1"
5) "set1"
6) "zseta"
7) "list1"
8) "key3"
9) "set3"
10) "key"
127.0.0.1:6379> keys set3
1) "set3"

slowlog get //列出所有的慢查询日志

127.0.0.1:6379> SLOWLOG get
1)   1) (integer) 3
   2) (integer) 1534932157
   3) (integer) 23
   4) 1) "keys"
      2) "set3"
   5) "127.0.0.1:44242"
   6) ""
2)   1) (integer) 2
   2) (integer) 1534932144
   3) (integer) 61
   4) 1) "keys"
      2) "*"
   5) "127.0.0.1:44242"
   6) ""
3)   1) (integer) 1
   2) (integer) 1534932130
   3) (integer) 18
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""
4)   1) (integer) 0
   2) (integer) 1534932088
   3) (integer) 1035
   4) 1) "COMMAND"
   5) "127.0.0.1:44242"
   6) ""

slowlog get 1 //列出最近的1条慢查询

127.0.0.1:6379> SLOWLOG get 1
1)   1) (integer) 4
   2) (integer) 1534932175
   3) (integer) 389
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""

slowlog get 2 //只列出最近的2条

 127.0.0.1:6379> SLOWLOG get 2
1)  1) (integer) 5
   2) (integer) 1534932261
   3) (integer) 43
   4)   1) "SLOWLOG"
      2) "get"
      3) "1"
   5) "127.0.0.1:44242"
   6) ""
2)  1) (integer) 4
   2) (integer) 1534932175
   3) (integer) 389
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""

slowlog len //查看慢查询日志条数

127.0.0.1:6379> SLOWLOG len
(integer) 7

21.19 php安装redis扩展

PHP中使用redis – 安装扩展模块

cd /usr/local/src
wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip
unzip phpredis.zip
cd phpredis-develop
/usr/local/php-fpm/bin/phpize
./configure --with-php-config=/usr/local/php-fpm/bin/php-config
make 
make install
vim /usr/local/php.ini 
##增加extension=redis.so
##看是否有redis模块
/usr/local/php-fpm/bin/php -m|grep redis
redis
##重启php-fpm服务

21.20 redis存储session

PHP中使用redis – 存储session

vim /usr/local/php-fpm/etc/php.ini
#更改或增加
session.save_handler = "redis" 
session.save_path = "tcp://127.0.0.1:6379"

或者apache虚拟主机配置文件中也可以这样配置:

php_value session.save_handler " redis" php_value session.save_path " tcp://127.0.0.1:6379"`

或者php-fpm配置文件对应的pool中增加:

vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
php_value[session.save_handler] = redis
php_value[session.save_path] = " tcp://127.0.0.1:6379 "

#顺便也可以把redis.conf的密码给删掉或者注释掉

vim /etc/redis.conf
#requirepass luolinux>aaa

下载测试文件

进入localhost的目录

cd /data/web/www.com/
wget http://study.lishiming.net/.mem_se.txt
mv .mem_se.txt  test.php

其中test.php内容可以参考https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/21NOSQL/session.php 或者手动添加php测试参数

vim test.php  
<?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();
?>

多次curl 取key-value数据

[root@localhost ~]# curl localhost/11.php
1535016218<br><br>1535016218<br><br>mh2404u6koq5s7q8lvmothf385
[root@localhost ~]# curl localhost/11.php
1535016219<br><br>1535016219<br><br>nsvpsvca8kgg0ars2gpjavm5g2
[root@localhost ~]# curl localhost/11.php
1535016219<br><br>1535016219<br><br>gvus9tekjoaac0i2d9lu0g12d1
[root@localhost ~]# curl localhost/11.php
1535016220<br><br>1535016220<br><br>mp9rmfj0f0simu450hp1gkh090
[root@localhost ~]# curl localhost/11.php
1535016220<br><br>1535016220<br><br>jorriqau86qu9t9appjg94m4f2

进入数据库

查key值

[root@localhost ~]# redis-cli
127.0.0.1:6379> keys *
1) "key1"
2) "PHPREDIS_SESSION:jorriqau86qu9t9appjg94m4f2"
3) "key2"
4) "PHPREDIS_SESSION:mh2404u6koq5s7q8lvmothf385"
5) "list1"
6) "PHPREDIS_SESSION:nsvpsvca8kgg0ars2gpjavm5g2"
7) "PHPREDIS_SESSION:mp9rmfj0f0simu450hp1gkh090"
8) "set3"
9) "list11"
10) "set1"
11) "zseta"
12) "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
13) "hash1"
14) "seta"
15) "key10"
16) "key3"
17) "set2"
18) "PHPREDIS_SESSION:gvus9tekjoaac0i2d9lu0g12d1"

查看key的value

127.0.0.1:6379> get "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
"TEST|i:1535016167;TEST3|i:1535016167;"
解释:
get "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
#这个是key
"TEST|i:1535016167;TEST3|i:1535016167;"
#这个是value
 针对redis集群

如果想用php连接redis cluster,需要使用predis扩展 安装方法类似phpredis,predis扩展地址https://github.com/nrk/predis

21.21 redis主从配置

Redis主从复制原理: 通过把这个RDB文件或AOF文件传给slave服务器,slave服务器重新加载RDB文件,来实现复制的功能!

复制的话:主服务器可以有多个从服务器!!! 不仅这样从服务器还可以有从服务器,可以做成星状的结构! 复制的话也不会阻塞进程,同样fork一个子进程来做!

复制的原理: 当建立一个从服务器后,从服务器会想主服务器发送一个SYNC的命令,主服务器接收到SYNC命令之后会执行BGSAVE 然后保存到RDB文件,然后发送到从服务器!收到RDB文件然后就载入到内存!

配置非常简单: 要把:192.168.66.131 6380 作为192.168.66.131 6379的从就一条命令

192.168.66.131:6380> slaveof 192.168.66.131 6379
OK
然后使用INFO查看下:
192.168.66.131:6380>INFO
# Replication
role:slave
master_host:192.168.66.131
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:85
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

然后在到主的上面看下:

[root@localhost ~]# redis-cli -h 192.168.66.131 -p 6379
192.168.66.131:6379> INFO
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.66.131,port=6380,state=online,offset=183,lag=1    #
master_repl_offset:183
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:182

从2.61 的时候!从是仅读的

192.168.66.131:6380> SET key1 2
(error) READONLY You can't write against a read only slave.

21.22 redis集群介绍

多个redis节点网络互联,数据共享 所有的节点都是一主一从(可以是多个从),其中从不提供服务,仅作为备用 不支持同时处理多个键(如mset/mget),因为redis需要把键均匀分布在各个节点上,并发量很高的情况下同时创建键值会降低性能并导致不可预测的行为。 支持在线增加、删除节点 客户端可以连任何一个主节点进行读写

21.23/21.24 redis集群搭建配置

场景设置: 两台机器,分别开启三个Redis服务(端口) A机器上三个端口7000,7002,7004,全部为主 B机器上三个端口7001,7003,7005,全部为从 两台机器上都要编译安装redis,然后编辑并复制3个不同的redis.conf,分别设置不同的端口号、dir等参数,还需要增加cluster相关参数,然后分别启动6个redis服务 具体redis配置文件大家到https://coding.net/u/aminglinux/p/yuanke_centos7/git/tree/master/21NOSQL下载或者查看

安装ruby2.2 (只需要一台机器上运行)

yum -y groupinstall "Development Tools"
yum -y install gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-deve
cd /root/
mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P rpmbuild/SOURCES
wget https://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P rpmbuild/SPECS
rpmbuild -bb rpmbuild/SPECS/ruby22x.spec
yum -y localinstall rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
gem install redis

21.25 redis集群操作

cp /usr/local/src/redis-4.0.1/src/redis-trib.rb /usr/bin/
redis-trib.rb create --replicas 1 192.168.133.130:7000 192.168.133.130:7002 192.168.133.130:7004 192.168.133.132:7001 192.168.133.132:7003 192.168.133.132:7005
redis-cli -c -h 192.168.133.130 -p 7000//-c说明以集群的方式登录
任意一个节点都可以创建key,或者查看key(演示)
redis-trib.rb check 192.168.133.130:7000//检测集群状态
cluster nodes//列出节点
cluster info//查看集群信息
cluster meet ip port //添加节点
cluster forget node_id //移除某个节点
cluster replicate node_id//将当前节点设置为指定节点的从
cluster saveconfig//保存配置文件

扩展 redis 哨兵https://segmentfault.com/a/1190000002680804 http://www.cnblogs.com/jaycekon/p/6237562.html