21.9 redis介绍
Redis 和 Memcached 类似,也属于 k-v 数据存储
Redis 官网 redis.io, 当前最新稳定版4.0.1
支持更多 value 类型,除了和 string 外,还支持 hash、lists(链表)、sets(集合)和sorted sets(有序集合)
redis 使用了两种文件格式:全量数据(RDB)和增量请求(aof)。全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载。增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行 replay 得到数据,这种类似于 mysql binlog。
redis 的存储分为内存存储、磁盘存储和 log 文件三部分
21.10 redis安装
1、下载稳定版、解压
[root@arslinux-01 ~]# cd /usr/local/src/ [root@arslinux-01 src]# wget http://download.redis.io/releases/redis-4.0.1.tar.gz [root@arslinux-01 src]# tar xvf redis-4.0.1.tar.gz [root@arslinux-01 src]# cd redis-4.0.1/
2、编译安装(没有./config 这一步)
[root@arslinux-01 redis-4.0.1]# make && make install [root@arslinux-01 redis-4.0.1]# echo $? 0
3、拷贝 redis.conf 到 /etc/ 下
[root@arslinux-01 redis-4.0.1]# which redis-cli /usr/local/bin/redis-cli [root@arslinux-01 redis-4.0.1]# cp redis.conf /etc/
4、编辑配置文件 redis.conf
[root@arslinux-01 redis-4.0.1]# vim /etc/redis.conf daemonize yes //no 为前台启动 redis,yes 是后台启动redis,不会占用终端 pidfile /var/run/redis_6379.pid //指定 pid logfile "/var/log/redis.log" //定义 log 文件位置 dir /data/redis/ // rdb文件的位置 appendonly yes //是否开启 aof 文件,如果yes,则会在dir下创建appendonly.aof文件
5、创建 /data/redis/目录
[root@arslinux-01 redis-4.0.1]# mkdir /data/redis/
6、更改两个内核参数,以免发生错误,并放入 /etc/rc.local,让机器一启动就执行
[root@arslinux-01 redis-4.0.1]# sysctl vm.overcommit_memory=1 vm.overcommit_memory = 1 [root@arslinux-01 redis-4.0.1]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@arslinux-01 redis-4.0.1]# vim /etc/rc.local sysctl vm.overcommit_memory=1 echo never > /sys/kernel/mm/transparent_hugepage/enabled
7、启动 redis
[root@arslinux-01 redis-4.0.1]# redis-server /etc/redis.conf [root@arslinux-01 redis-4.0.1]# ps aux|grep redis root 11963 0.3 0.7 145300 7536 ? Ssl 19:57 0:00 redis-server 127.0.0.1:6379 root 11972 0.0 0.0 112724 988 pts/0 S+ 19:57 0:00 grep --color=auto redis
21.11 redis持久化
Redis提供了两种持久化方式,是 RDB(Redis DataBase)和 AOF(Append Only File)
RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上。
AOF,则是换了一个角度来实现持久化,那就是将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实 RDB 和 AOF 两种方式也可以同时使用,在这种情况下,如果 redis 重启的话,则会优先采用 AOF 方式来进行数据恢复,这是因为 AOF 方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭 RDB 和 AOF 方式,这样的话,redis 将变成一个纯内存数据库,就像 memcache 一样。
Redis持久化相关参数:
save 900 1 //表示每15分钟且至少有1个key改变,就触发一次持久化
save 300 10 //表示每5分钟且至少有10个key改变,就触发一次持久化
save 60 10000 //表示每60秒至少有10000个key改变,就触发一次持久
save “” //这样可以禁用rdb持久化
appendonly yes //如果是yes,则开启 aof 持久化
appendfilename “appendonly.aof” // 指定 aof 文件名字
appendfsync everysec //指定fsync()调用模式,有三种no(不调用fsync),always(每次写都会调用fsync),everysec(每秒钟调用一次fsync)。第一种最快,第二种数据最安全,但性能会差一些,第三种为这种方案,默认为第三种。
21.12 redis 数据类型
1、string
string 为最简单的类型,与 Memcached 一样的类型,一个 key 对应一个 value,其支持的操作与 Memcached 的操作类似,它的功能更丰富。设置可以存二进制的对象。
示例:
[root@arslinux-01 redis-4.0.1]# redis-cli 127.0.0.1:6379> set mykey 123 OK 127.0.0.1:6379> get mykey "123" 127.0.0.1:6379> mset k1 1 k2 2 k3 a OK 127.0.0.1:6379> mget k1 k2 k3 1) "1" 2) "2" 3) "a"
2、list
list是一个链表结构,主要功能是 push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行。
示例:
127.0.0.1:6379> LPUSH list1 "arslinux" (integer) 1 127.0.0.1:6379> LPUSH list1 "123" (integer) 2 127.0.0.1:6379> LPUSH list1 "aaa" (integer) 3
127.0.0.1:6379> LRANGE list1 0 -1 1) "aaa" 2) "123" 3) "arslinux"
127.0.0.1:6379> LPOP list1 "aaa" 127.0.0.1:6379> LRANGE list1 0 -1 1) "123" 2) "arslinux"
3、set
set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
示例:
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 set1 c (integer) 1
127.0.0.1:6379> SMEMBERS set1//合集 1) "c" 2) "a" 3) "b"
127.0.0.1:6379> SADD set2 a (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 c (integer) 1 127.0.0.1:6379> SMEMBERS set2 1) "c" 2) "2" 3) "3" 4) "a"
127.0.0.1:6379> SUNION set1 set2 //并集 1) "a" 2) "b" 3) "2" 4) "3" 5) "c"
127.0.0.1:6379> SINTER set1 set2 //交集 1) "c" 2) "a"
127.0.0.1:6379> SDIFF set1 set2 //差集,集合前后顺序会影响结果 1) "b" 127.0.0.1:6379> SDIFF set2 set1 1) "2" 2) "3"
127.0.0.1:6379> SREM set1 c //删除 (integer) 1 127.0.0.1:6379> SMEMBERS set1 1) "a" 2) "b"
4、sort set
sorted set 是有序集合,它比set多了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的 Sorted Sets,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。
示例:
127.0.0.1:6379> ZADD set3 12 abc (integer) 1 127.0.0.1:6379> ZADD set3 2 "cde 123" (integer) 1 127.0.0.1:6379> ZADD set3 24 "arslinux" (integer) 1 127.0.0.1:6379> ZADD set3 4 "arsenal" (integer) 1
127.0.0.1:6379> ZRANGE set3 0 -1 1) "cde 123" 2) "arsenal" 3) "abc" 4) "arslinux"
127.0.0.1:6379> ZREVRANGE set3 0 -1//倒序 1) "arslinux" 2) "abc" 3) "arsenal" 4) "cde 123"
5、hash
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。
示例:
127.0.0.1:6379> HSET hash1 name arslinux (integer) 1 127.0.0.1:6379> HSET hash1 age 30 (integer) 1 127.0.0.1:6379> HSET hash1 job it (integer) 1
127.0.0.1:6379> HGET hash1 age "30" 127.0.0.1:6379> HGET hash1 name "arslinux"
127.0.0.1:6379> HGETALL hash1 //全部显示,奇数行key,偶数行value 1) "name" 2) "arslinux" 3) "age" 4) "30" 5) "job" 6) "it"
21.13/21.14/21.15 redis常用操作
1、string
127.0.0.1:6379> set key1 arslinux OK 127.0.0.1:6379> set key2 linux OK 127.0.0.1:6379> set key1 linux //第二次赋值会覆盖 OK 127.0.0.1:6379> get key1 "linux"
setnx 检查key是否存在,不存在则创建
127.0.0.1:6379> setnx key1 aaa//key1存在,返回 0 (integer) 0 127.0.0.1:6379> setnx key3 aaa//key3不存在,返回 1,直接创建 key3 (integer) 1 127.0.0.1:6379> get key3 "aaa"
设置过期时间:
127.0.0.1:6379> set key3 aaa ex 10 OK 127.0.0.1:6379> get key3 "aaa" 127.0.0.1:6379> get key3 (nil)
setex 设置过期时间
127.0.0.1:6379> setex key3 1000 bbb OK
2、list
127.0.0.1:6379> LPUSH list2 aaa//从左侧加入一个元素 (integer) 1 127.0.0.1:6379> LPUSH list2 bbb (integer) 2 127.0.0.1:6379> LRANGE list2 0 -1 1) "bbb" 2) "aaa"
127.0.0.1:6379> LPOP list2//从左侧取出第一个元素 "bbb"
127.0.0.1:6379> LPUSH list2 ccc (integer) 2 127.0.0.1:6379> LPUSH list2 ddd (integer) 3 127.0.0.1:6379> LRANGE list2 0 -1 1) "ddd" 2) "ccc" 3) "aaa"
127.0.0.1:6379> RPOP list2//从右侧取出第一个元素 "aaa"
127.0.0.1:6379> LINSERT list2 after ccc aaa //在 ccc 后插入一个元素叫 aaa (integer) 3 127.0.0.1:6379> LINSERT list2 after aaa bbb (integer) 4 127.0.0.1:6379> LRANGE list2 0 -1 1) "ddd" 2) "ccc" 3) "aaa" 4) "bbb"
127.0.0.1:6379> LSET list2 1 111 //修改第2个元素为 111 OK 127.0.0.1:6379> LRANGE list2 0 -1 1) "ddd" 2) "111" 3) "aaa" 4) "bbb" 127.0.0.1:6379> LSET list2 0 123 OK 127.0.0.1:6379> LRANGE list2 0 -1 1) "123" 2) "111" 3) "aaa" 4) "bbb"
127.0.0.1:6379> LINDEX list2 3//查看第4个元素 "bbb" 127.0.0.1:6379> LLEN list2//查看链表有几个元素 (integer) 4
3、set
127.0.0.1:6379> SADD seta aaa //向集合 seta 中加入元素 (integer) 1 127.0.0.1:6379> SADD seta bbb (integer) 1 127.0.0.1:6379> SMEMBERS seta //查看集合中所有元素 1) "bbb" 2) "aaa"
127.0.0.1:6379> SREM seta aaa //删除元素 (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "bbb"
127.0.0.1:6379> SPOP seta //随机取出一个元素,删除 "bbb" 127.0.0.1:6379> SMEMBERS seta (empty list or set)
127.0.0.1:6379> SADD seta ccc (integer) 1 127.0.0.1:6379> SADD seta 111 (integer) 1 127.0.0.1:6379> SADD setb 111 (integer) 1 127.0.0.1:6379> SADD setb 222 (integer) 1 127.0.0.1:6379> SADD setb aaa (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "111" 2) "ccc" 127.0.0.1:6379> SMEMBERS setb 1) "222" 2) "111" 3) "aaa"
127.0.0.1:6379> SDIFF seta setb //以 seta 为标准,求差集 1) "ccc" 127.0.0.1:6379> SDIFF setb seta //以 setb 为标准,求差集 1) "222" 2) "aaa"
127.0.0.1:6379> SDIFFSTORE setc seta setb//求差集并且存储,存储到了setc里 (integer) 1 127.0.0.1:6379> SMEMBERS setc 1) "ccc"
127.0.0.1:6379> SINTER seta setb //求交集 1) "111" 127.0.0.1:6379> SINTERSTORE setd seta setb //求交集并储存 setd (integer) 1 127.0.0.1:6379> SMEMBERS setd 1) "111"
127.0.0.1:6379> SUNION seta setb//求并集 1) "222" 2) "111" 3) "aaa" 4) "ccc"
127.0.0.1:6379> SUNIONSTORE sete seta setb//求并集并储存 sete (integer) 4 127.0.0.1:6379> SMEMBERS sete 1) "222" 2) "111" 3) "aaa" 4) "ccc"
127.0.0.1:6379> SISMEMBER seta aaa //判断一个元素是否属于一个集合 (integer) 0 127.0.0.1:6379> SISMEMBER seta ccc (integer) 1
127.0.0.1:6379> SRANDMEMBER seta //随机取出一个元素,但不删除 "ccc" 127.0.0.1:6379> SRANDMEMBER seta 2 //随机去两个元素,但不删除(可设置取几个元素) 1) "111" 2) "ccc" 127.0.0.1:6379> SMEMBERS seta 1) "111" 2) "ccc"
4、zset
127.0.0.1:6379> ZADD zseta 11 123 //创建有序集合 (integer) 1 127.0.0.1:6379> ZADD zseta 0 1ab (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 //显示所有元素,按顺序显示 1) "1ab" 2) "123"
127.0.0.1:6379> ZREM zseta 1ab //删除指定元素 (integer) 1 127.0.0.1:6379> zrange zseta 0 -1 1) "123"
127.0.0.1:6379> ZADD zseta 10 1ab (integer) 1 127.0.0.1:6379> ZADD zseta 14 sssab (integer) 1 127.0.0.1:6379> ZADD zseta 16 12121212 (integer) 1 127.0.0.1:6379> ZADD zseta 1000 asdfasdf1212 (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 1) "1ab" 2) "123" 3) "sssab" 4) "12121212" 5) "asdfasdf1212"
127.0.0.1:6379> ZRANK zseta sssab //返回元素的索引值,索引值从0开始,按score正向排序 (integer) 2
127.0.0.1:6379> ZREVRANK zseta 12121212 //同上,不同的是,按score反序排序 (integer) 1
127.0.0.1:6379> ZREVRANGE zseta 0 -1 //反序显示所有元素,并带分值,和ZRANGE相反 1) "asdfasdf1212" 2) "12121212" 3) "sssab" 4) "123" 5) "1ab"
127.0.0.1:6379> ZCARD zseta //返回集合中所有元素的个数 (integer) 5
127.0.0.1:6379> ZCOUNT zseta 50 10000 //返回分值范围1-10的元素个数 (integer) 1 127.0.0.1:6379> ZCOUNT zseta 10 10000 (integer) 5
127.0.0.1:6379> ZRANGEBYSCORE zseta 10 19 //返回分值范围10-19的元素 1) "1ab" 2) "123" 3) "sssab" 4) "12121212"
127.0.0.1:6379> ZREMRANGEBYSCORE zseta 10 11 //删除分值范围10-11的元素 (integer) 2 127.0.0.1:6379> ZREVRANGE zseta 0 -1 1) "asdfasdf1212" 2) "12121212" 3) "sssab"
127.0.0.1:6379> ZREMRANGEBYRANK zseta 0 2 //删索引范围0-2的元素,按score正向排序 (integer) 3 127.0.0.1:6379> ZREVRANGE zseta 0 -1 (empty list or set)
5、hash
127.0.0.1:6379> HMSET hash2 a 1 b 2 c 3 d 4 //批量建立键值对 OK 127.0.0.1:6379> HGETALL hash2 1) "a" 2) "1" 3) "b" 4) "2" 5) "c" 6) "3" 7) "d" 8) "4"
127.0.0.1:6379> HMGET hash2 b c //批量获取键值对 1) "2" 2) "3"
127.0.0.1:6379> HGETALL hash2 //删除指定filed 1) "a" 2) "1" 3) "c" 4) "3" 5) "d" 6) "4"
127.0.0.1:6379> hkeys hash2 //打印所有的key 1) "a" 2) "c" 3) "d"
127.0.0.1:6379> HVALS hash2 //打印所有values 1) "1" 2) "3" 3) "4"
127.0.0.1:6379> HLEN hash2 //查看hash有几个filed (integer) 3
21.16 redis 操作键值
127.0.0.1:6379> keys * //取出所有 key 1) "k3" 2) "setc" 3) "set2" 4) "setb" 5) "mykey" 6) "setd" 7) "list2" 8) "seta" 9) "k1" 10) "set1" 11) "key1" 12) "hash1" 13) "set3" 14) "key2" 15) "k2" 16) "sete" 17) "hash2" 18) "list1"
127.0.0.1:6379> keys k* //模糊匹配 1) "k3" 2) "k1" 3) "key1" 4) "key2" 5) "k2"
127.0.0.1:6379> EXISTS key1 //有key是否存在,存在返回1 ,否则返回0 (integer) 1 127.0.0.1:6379> EXISTS key2 (integer) 1 127.0.0.1:6379> EXISTS key11 (integer) 0
127.0.0.1:6379> del key1 // 删除一个key,成功返回1 ,否则返回0 (integer) 1 127.0.0.1:6379> get key1 (nil)
127.0.0.1:6379> EXPIRE k2 10 //设置k2 10s后过期 (integer) 1 127.0.0.1:6379> get k2 "2" 127.0.0.1:6379> get k2 "2" 127.0.0.1:6379> get k2 (nil)
127.0.0.1:6379> EXPIRE key2 160 //设置key2 160s后过期 (integer) 1 127.0.0.1:6379> ttl key2 // 查看键还有多长时间过期,单位是s,当key不存在时,返回-2当key存在但没有设置剩余生存时间时,返回-1 。否则返回key的剩余生存时间。 (integer) 156 127.0.0.1:6379> ttl key2 (integer) 153 127.0.0.1:6379> ttl key2 (integer) 148 127.0.0.1:6379> ttl key2 (integer) 16 127.0.0.1:6379> ttl key2 (integer) -2
127.0.0.1:6379> SELECT 0 //代表选择当前数据库,默认进入0数据库 OK 127.0.0.1:6379> keys * 1) "k3" 2) "setc" 3) "set2" 4) "setb" 5) "mykey" 6) "setd" 7) "list2" 8) "seta" 9) "k1" 10) "set1" 11) "hash1" 12) "set3" 13) "sete" 14) "hash2" 15) "list1" 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6379[1]> keys * (empty list or set)
127.0.0.1:6379> MOVE set2 1 // 把 set2 移动到 1 数据库 (integer) 1 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6379[1]> keys * 1) "set2"
127.0.0.1:6379> EXPIRE mykey 1000 //取消key1的过期时间 (integer) 1 127.0.0.1:6379> ttl mykey (integer) 997 127.0.0.1:6379> PERSIST mykey (integer) 1 127.0.0.1:6379> ttl mykey (integer) -1
127.0.0.1:6379> RANDOMKEY //随机返回一个key "sete" 127.0.0.1:6379> RANDOMKEY "k1" 127.0.0.1:6379> RANDOMKEY "setb" 127.0.0.1:6379> RANDOMKEY "list2"
127.0.0.1:6379> RENAME setb set3 //重命名key OK 127.0.0.1:6379> keys set* 1) "setc" 2) "setd" 3) "seta" 4) "set1" 5) "set3" 6) "sete"
127.0.0.1:6379> type seta //返回键的类型 set 127.0.0.1:6379> type hash2 hash 127.0.0.1:6379> type mykey string
127.0.0.1:6379> DBSIZE //返回当前数据库中key的数目 (integer) 13 127.0.0.1:6379> keys * 1) "k3" 2) "setc" 3) "mykey" 4) "setd" 5) "list2" 6) "seta" 7) "k1" 8) "set1" 9) "hash1" 10) "set3" 11) "sete" 12) "hash2" 13) "list1
127.0.0.1:6379> info//返回redis数据库状态信息 # Server redis_version:4.0.1 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:b8bc562e9b5ddc70 redis_mode:standalone os:Linux 3.10.0-957.el7.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:4.8.5 process_id:11963 run_id:430133d65f76a9090627914095bc6226b1be71e7 tcp_port:6379 uptime_in_seconds:9531 uptime_in_days:0 hz:10 lru_clock:2833915 executable:/usr/local/src/redis-4.0.1/redis-server config_file:/etc/redis.conf # Clients connected_clients:1 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:830088 used_memory_human:810.63K used_memory_rss:7983104 used_memory_rss_human:7.61M used_memory_peak:830088 used_memory_peak_human:810.63K used_memory_peak_perc:100.09% used_memory_overhead:816110 used_memory_startup:765600 used_memory_dataset:13978 used_memory_dataset_perc:21.68% total_system_memory:1019797504 total_system_memory_human:972.55M used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:9.62 mem_allocator:jemalloc-4.0.3 active_defrag_running:0 lazyfree_pending_objects:0 # Persistence loading:0 rdb_changes_since_last_save:5 rdb_bgsave_in_progress:0 rdb_last_save_time:1563114212 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:0 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:2441216 aof_enabled:1 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0 aof_current_size:3096 aof_base_size:0 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0 # Stats total_connections_received:1 total_commands_processed:205 instantaneous_ops_per_sec:0 total_net_input_bytes:6918 total_net_output_bytes:13605 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:4 evicted_keys:0 keyspace_hits:106 keyspace_misses:12 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:355 migrate_cached_sockets:0 slave_expires_tracked_keys:0 active_defrag_hits:0 active_defrag_misses:0 active_defrag_key_hits:0 active_defrag_key_misses:0 # Replication role:master connected_slaves:0 master_replid:ff9e1dbdf9eff911cfa86a9a8000a3a51c753e22 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:13.07 used_cpu_user:7.05 used_cpu_sys_children:0.15 used_cpu_user_children:0.01 # Cluster cluster_enabled:0 # Keyspace db0:keys=13,expires=0,avg_ttl=0 db1:keys=1,expires=0,avg_ttl=0
127.0.0.1:6379> SELECT 1 //清空当前数据库中所有的key 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)
127.0.0.1:6379[1]> FLUSHALL //清空所有数据库中的所有的key OK 127.0.0.1:6379[1]> SELECT 0 OK 127.0.0.1:6379> keys * (empty list or set)
127.0.0.1:6379> BGSAVE //保存数据到 rdb文件中,在后台运行 Background saving started 127.0.0.1:6379> SAVE //作用同上,但是在前台运行 OK
127.0.0.1:6379> CONFIG GET * //获取所有配置参数 1) "dbfilename" 2) "dump.rdb" ...... 167) "bind" 168) "127.0.0.1"
127.0.0.1:6379> CONFIG GET port //获取配置参数 1) "port" 2) "6379" 127.0.0.1:6379> CONFIG GET dir 1) "dir" 2) "/data/redis"
127.0.0.1:6379> CONFIG set timeout 1000 //更改配置参数 OK 127.0.0.1:6379> CONFIG GET timeout 1) "timeout" 2) "1000"
数据恢复: 首先定义或者确定 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"
21.17 redis安全设置
防止***利用 redis 漏洞进入 redis
设置监听ip
bind 127.0.0.1 2.2.2.2//可以是多个ip,用空格分隔
设置监听端口
port 16000
设置密码
1)编辑 redis.conf 配置文件,加入密码
[root@arslinux-01 ~]# vim /etc/redis.conf requirepass arslinux>com
2)重启 redis
[root@arslinux-01 ~]# systemctl restart redis Failed to restart redis.service: Unit not found. [root@arslinux-01 ~]# killall redis-server [root@arslinux-01 ~]# redis-server /etc/redis.conf
3)不用密码登录,是无法查看 keys 的
[root@arslinux-01 ~]# redis-cli 127.0.0.1:6379> keys * (error) NOAUTH Authentication required.
4)密码登录
[root@arslinux-01 ~]# redis-cli -a 'arslinux>com' 127.0.0.1:6379> keys * 1) "setc" 2) "setd" 3) "sete" 4) "seta" 5) "list1" 6) "set1" 7) "k3" 8) "k1" 9) "list2" 10) "hash1" 11) "set3" 12) "mykey" 13) "hash2"
配置文件中将 config 命令改名
找到 rename-command 位置,增加一行
[root@arslinux-01 ~]# vim /etc/redis.conf rename-command CONFIG arslinux
[root@arslinux-01 ~]# killall redis-server [root@arslinux-01 ~]# redis-server /etc/redis.conf
[root@arslinux-01 ~]# redis-cli -a "arslinux>com" 127.0.0.1:6379> CONFIG GET dir (error) ERR unknown command 'CONFIG' 127.0.0.1:6379> arslinux get dir 1) "dir" 2) "/data/redis"
禁掉 config 命令
编辑配置文件 /etc/redis.conf,设置命令为空
rename-command CONFIG “”
21.18 redis慢查询日志
针对慢查询日志,可以设置两个参数,一个是执行时长,单位是微秒,另一个是慢查询日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除
1、编辑配置文件 /etc/redis.conf
slowlog-log-slower-than 1000 //单位us,表示慢于1000us则记录日志
slowlog-max-len 128 //定义日志长度,表示最多存128条
2、测试
1)将 slowlog-log-slower-than 设置为10微秒,重启 redis
[root@arslinux-01 ~]# vim /etc/redis.conf slowlog-log-slower-than 10
[root@arslinux-01 ~]# killall redis-server [root@arslinux-01 ~]# redis-server /etc/redis.conf
[root@arslinux-01 ~]# redis-cli -a 'arslinux>com' 127.0.0.1:6379> SLOWLOG get 1) 1) (integer) 0 2) (integer) 1563117351 3) (integer) 738 4) 1) "COMMAND" 5) "127.0.0.1:52340" 6) "" 127.0.0.1:6379> keys * 1) "k3" 2) "hash1" 3) "list2" 4) "hash2" 5) "seta" 6) "set1" 7) "list1" 8) "setd" 9) "setc" 10) "mykey" 11) "k1" 12) "sete" 13) "set3" 127.0.0.1:6379> get k3 "a" 127.0.0.1:6379> SLOWLOG get 1) 1) (integer) 2 2) (integer) 1563117380 3) (integer) 47 4) 1) "keys" 2) "*" 5) "127.0.0.1:52340" 6) "" 2) 1) (integer) 1 2) (integer) 1563117356 3) (integer) 34 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:52340" 6) "" 3) 1) (integer) 0 2) (integer) 1563117351 3) (integer) 738 4) 1) "COMMAND" 5) "127.0.0.1:52340" 6) ""
127.0.0.1:6379> SLOWLOG get 2//只列出最新的2条 1) 1) (integer) 4 2) (integer) 1563117461 3) (integer) 20 4) 1) "SLOWLOG" 2) "get" 3) "1" 5) "127.0.0.1:52340" 6) "" 2) 1) (integer) 3 2) (integer) 1563117386 3) (integer) 48 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:52340" 6) ""
127.0.0.1:6379> SLOWLOG len//查看慢查询日志条数 (integer) 6
21.19 php 安装 redis 扩展
1、下载、解压
[root@arslinux-01 ~]# cd /usr/local/src/ [root@arslinux-01 src]# wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip
2、生成 .config 文件
[root@arslinux-01 src]# cd phpredis-develop/ [root@arslinux-01 phpredis-develop]# /usr/local/php-fpm/bin/phpize \Configuring for: PHP Api Version: 20131106 Zend Module Api No: 20131226 Zend Extension Api No: 220131226
3、编译安装
[root@arslinux-01 phpredis-develop]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config [root@arslinux-01 phpredis-develop]# make && make install
4、编辑 php.ini,增加一行 extension=redis.so
[root@arslinux-01 phpredis-develop]# vim /usr/local/php-fpm/etc/php.ini extension=redis.so
5、检查 redis 模块是否安装成功
[root@arslinux-01 phpredis-develop]# /usr/local/php-fpm/bin/php -m |grep redis redis
6、重启 php-fpm 服务
[root@arslinux-01 phpredis-develop]# /etc/init.d/php-fpm restart Gracefully shutting down php-fpm . done Starting php-fpm done
21.20 redis 存储 session
1、根据之前的经验,直接在 php-fpm 配置对应的 pool 里增加
[root@arslinux-01 phpredis-develop]# vim /usr/local/php-fpm/etc/php-fpm.d/arslinux.conf php_value[session.save_handler] = redis php_value[session.save_path] = "tcp://127.0.0.1:6379"
2、重启 php-fpm 和 去除密码配置 重启redis
[root@arslinux-01 phpredis-develop]# /etc/init.d/php-fpm restart Gracefully shutting down php-fpm . done Starting php-fpm done [root@arslinux-01 phpredis-develop]# killall redis-server [root@arslinux-01 phpredis-develop]# redis-server /etc/redis.conf
3、下载测试文件
因为之前已经下载了,在 /data/wwwroot/default/下并改名为 1.php
4、直接 curl
[root@arslinux-01 default.com]# curl localhost/1.php 1563118794<br><br>1563118794<br><br>5tih1g88dm4amd6614iihfuvb2 [root@arslinux-01 default.com]# curl localhost/1.php 1563118796<br><br>1563118796<br><br>70rnt7unik8eie33co32pdg155 [root@arslinux-01 default.com]# curl localhost/1.php 1563118799<br><br>1563118799<br><br>i9pmk3ht9nccqro6vh1c6bnh16 [root@arslinux-01 default.com]# curl localhost/1.php 1563118800<br><br>1563118800<br><br>3sgv8fmn2csf5vmcsbgbaqf351 [root@arslinux-01 default.com]# curl localhost/1.php 1563118801<br><br>1563118801<br><br>1lrs39of4hashv86t2rntr5tc0
5、进入 redis,查看 keys 对应的 value是否匹配
[root@arslinux-01 default.com]# redis-cli 127.0.0.1:6379> keys * 1) "set3" 2) "PHPREDIS_SESSION:i9pmk3ht9nccqro6vh1c6bnh16" 3) "setc" 4) "PHPREDIS_SESSION:1lrs39of4hashv86t2rntr5tc0" 5) "list1" 6) "sete" 7) "list2" 8) "hash1" 9) "PHPREDIS_SESSION:3sgv8fmn2csf5vmcsbgbaqf351" 10) "seta" 11) "PHPREDIS_SESSION:70rnt7unik8eie33co32pdg155" 12) "PHPREDIS_SESSION:5tih1g88dm4amd6614iihfuvb2" 13) "setd" 14) "mykey" 15) "set1" 16) "k1" 17) "k3" 18) "hash2" 127.0.0.1:6379> get PHPREDIS_SESSION:5tih1g88dm4amd6614iihfuvb2 "TEST|i:1563118794;TEST3|i:1563118794;" 127.0.0.1:6379> get PHPREDIS_SESSION:70rnt7unik8eie33co32pdg155 "TEST|i:1563118796;TEST3|i:1563118796;"
6、成功!!
还有两种方法:
1、vim /usr/local/php-fpm/etc/php.ini//更改或增加
session.save_handler = "redis"
session.save_path = "tcp://127.0.0.1:6379"
2、apache虚拟主机配置文件中也可以这样配置:
php_value session.save_handler " redis" php_value session.save_path " tcp://127.0.0.1:6379"
如果想用 php 连接 redis cluster,需要使用 predis 扩展
安装方法类似 phpredis,predis 扩展地址 https://github.com/nrk/predis
21.21 redis主从配置
为了节省资源,我们可以在一台机器上启动两个redis服务
1、拷贝配置文件并根据实际更改,以区分两个 redis
[root@arslinux-01 ~]# cp /etc/redis.conf /etc/redis2.conf [root@arslinux-01 ~]# vim /etc/redis2.conf port 6380 pidfile /var/run/redis_6380.pid logfile "/var/log/redis2.log" dir /data/redis2/ slaveof 127.0.0.1 6379 //增加一行主服务器的ip,端口号
如果主配置了 requirepass ,那么从上也需要配置同样的设置
2、创建 redis2 的目录
[root@arslinux-01 ~]# mkdir /data/redis2/
3、启动 reids2
[root@arslinux-01 ~]# redis-server /etc/redis2.conf [root@arslinux-01 ~]# ps aux|grep redis root 8128 0.3 0.9 147348 9856 ? Ssl 12:03 0:00 redis-server 127.0.0.1:6379 root 8151 0.0 0.9 147348 9736 ? Ssl 12:03 0:00 redis-server 127.0.0.1:6380 root 8158 0.0 0.0 112724 988 pts/0 R+ 12:03 0:00 grep --color=auto redis [root@arslinux-01 ~]# netstat -lntp |grep redis tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 8128/redis-server 1 tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 8151/redis-server 1
4、测试
[root@arslinux-01 ~]# redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> keys * 1) "set1" 2) "setd" 3) "set3" 4) "mykey" 5) "sete" 6) "list2" 7) "setc" 8) "hash2" 9) "hash1" 10) "list1" 11) "seta" 12) "k3" 13) "k1"
[root@arslinux-01 ~]# redis-cli -h 127.0.0.1 -p 6380 127.0.0.1:6380> keys * 1) "set1" 2) "k1" 3) "seta" 4) "hash2" 5) "mykey" 6) "hash1" 7) "setc" 8) "sete" 9) "list1" 10) "k3" 11) "list2" 12) "set3" 13) "setd"
127.0.0.1:6380> CONFIG GET dir (error) ERR unknown command 'CONFIG' 127.0.0.1:6380> arslinux get dir 1) "dir" 2) "/data/redis2" 127.0.0.1:6380> arslinux get dbfilename 1) "dbfilename" 2) "dump.rdb" 127.0.0.1:6380> arslinux get slaveof 1) "slaveof" 2) "127.0.0.1 6379" 127.0.0.1:6380> set key19 111 (error) READONLY You can't write against a read only slave.
因为配置文件中 slave-read-only yes 限制了只能读不可写,改为 no 则可写
注意:redis主从和mysql主从不一样,redis主从不用事先同步数据,它会自动同步过去