内容摘要
一、 redis介绍
二、 redis安装
三、 redis持久化
四、 redis数据类型
五、 redis常用操作
六、 redis操作键值
七、 redis安全设置
八、 redis慢查询日志
九、 php安装redis扩展
十、 redis存储session
十一、 redis主从配置
十二、 redis集群介绍
十三、 redis集群搭建配置
十四、 redis集群操作
一、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文件三部分
二、Redis安装
- 移动到/usr/local/src/目录,下载最新稳定版的redis。
cd /usr/local/src/
前往官网,下载最新稳定版(11月17日版本5.0.0):
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
解压
tar zxvf redis-5.0.0.tar.gz
- redis不需要初始化 直接编译安装
make && make install
- 拷贝解压目录下的配置文件到/etc/目录下。
cp redis.conf /etc/redis.conf
- 修改如下配置
vim /etc/redis.conf
修改内容如下:
daemonize yes ##是否在后台运行
logfile "/var/log/redis.log" ##定义日志文件路径
dir /data/redis/ ##定义RDB,aof文件的存放路径
appendonly yes ##开启aof日志,在dir定义的目录下存aof文件
- 创建RDB目录
mkdir /data/redis/
- 修改内核参数
sysctl vm.overcommit_memory=1
echo never > /sys/kernel/mm/transparent_hugepage/enabled
##上面两条命令是为了不让系统告警(可在redis日志中提示),不输入也没关系。想让机器启动就加载两条命令可以放到/etc/rc.local中:
redis-server /etc/redis.conf
echo never > /sys/kernel/mm/transparent_hugepage/enabled
- 启动redis服务
redis-server /etc/redis.conf
##查看服务是否启动
[root@aming-01 redis-5.0.0]# ps aux |grep redis
root 6064 0.0 0.2 153872 2316 ? Ssl 21:03 0:00 redis-server 127.0.0.1:6379
三、Redis持久化
- Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)
- RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上。
- AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
- 其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
- 如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。
- 在redis.conf文件中定义了一些的持久化相关参数
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)。第一种最快,第二种数据最安全,但性能会差一些,默认为第三种。
四、redis数据类型
- string
- string为最简单的类型,与Memcached一样的类型,一个key对应一个value,其支持的操作与Memcached的操作类似,它的功能更丰富。设置可以存二进制的对象。
- 连接redis(redis可以设置密码,默认没有所以可以直接通过命令连接)
redis-cli
- 添加或获得string类型数据
127.0.0.1:6379> set shenxinyu 25
OK
127.0.0.1:6379> set zhaozuoheng 1
OK
127.0.0.1:6379> get shenxinyu
"25"
127.0.0.1:6379> get zhaozuoheng
"1"
- 添加或获得多个string类型数据
127.0.0.1:6379> MSET a 1 b 2 c 3 d 4
OK
127.0.0.1:6379> MGET a b c d
1) "1"
2) "2"
3) "3"
4) "4"
- list
- list 链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行。 - 在链表中推进新数据
127.0.0.1:6379> LPUSH test 1
(integer) 1
127.0.0.1:6379> LPUSH test 2
(integer) 2
127.0.0.1:6379> LPUSH test 3
(integer) 3
- 查看键的值
127.0.0.1:6379> LRANGE test 0 -1 #其中-1表示末尾,即从头至尾。
1) "3"
2) "2"
3) "1"
- 在链表中拉出数据
127.0.0.1:6379> LPOP test
"3"
127.0.0.1:6379> LRANGE test 0 -1
1) "2"
2) "1"
- set
- set 集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
- 添加元素给集合
127.0.0.1:6379> sadd hah a
(integer) 1
127.0.0.1:6379> sadd hah 1
(integer) 1
127.0.0.1:6379> sadd hah c
(integer) 1
127.0.0.1:6379> sadd hhh a b c
(integer) 3
- 查看集合中的元素
127.0.0.1:6379> SMEMBERS hah
1) "c"
2) "a"
3) "1"
- 求并集
127.0.0.1:6379> SUNION hah hhh
1) "a"
2) "c"
3) "1"
4) "b"
- 求交集
127.0.0.1:6379> SINTER hah hhh
1) "c"
2) "a"
- 求差集
127.0.0.1:6379> SDIFF hhh hah
1) "b"
- 删除集合中的元素
127.0.0.1:6379> SREM hhh a
(integer) 1
127.0.0.1:6379> SMEMBERS hhh
1) "b"
2) "c"
- Sorted Set
- sorted set是有序集合,它比set多了一个权重参数score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的 Sorted Sets,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。
- 添加带权重的元素进集合
27.0.0.1:6379> ZADD set 1 zzz ##第三位即为权重score
(integer) 1
127.0.0.1:6379> ZADD set 2 abc
(integer) 1
127.0.0.1:6379> ZADD set 3 123
(integer) 1
- 查看有序集合
127.0.0.1:6379> ZRANGE set 0 -1 ##顺序从小到大
1) "zzz"
2) "abc"
3) "123"
- 倒序查看
127.0.0.1:6379> ZREVRANGE set 0 -1
1) "123"
2) "abc"
3) "zzz"
- hash
- hash 哈希表,类似于多个k-v组成的表。在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。
- 添加hash数据
127.0.0.1:6379> HSET hash1 name zhao
(integer) 1
127.0.0.1:6379> HSET hash1 age 26
(integer) 1
127.0.0.1:6379> HSET hash1 job IT
(integer) 1
- 查看hash表中的某个数据
127.0.0.1:6379> HGET hashtest name
"zhao"
127.0.0.1:6379> HGET hashtest job
"IT"
127.0.0.1:6379> HGET hashtest age
"26"
- 查看整个hash表
127.0.0.1:6379> HGETALL hashtest
1) "name" ##奇数行为key,偶数行为value
2) "zhao"
3) "age"
4) "26"
5) "job"
6) "IT"
四、redis常用操作
string
- 创建一个新的k-v
格式:
set 键名 值
127.0.0.1:6379> set key1 zzz
OK
- 获得k-v
格式:
get 键名
127.0.0.1:6379> get key1
"zzz"
- 当创建的键值已经存在时,再次创建会覆盖原先的值
127.0.0.1:6379> get key1
"zzz"
127.0.0.1:6379> set key1 sss
OK
127.0.0.1:6379> get key1
"sss"
- 检查k-v是否存在,返回不同结果
格式:
setnx 键名 值
127.0.0.1:6379> SETNX key1 aaa ##返回0表示该值已经存在 不创建
(integer) 0
127.0.0.1:6379> SETNX key2 bbb ##返回1表示该值不存在 自动创建该k-v
(integer) 1
127.0.0.1:6379> GET key2
"bbb"
- 给key3设置过期时间为10s,值为1,若key已经存在,会覆盖新的值
格式1:
setex 键名 过期时间(秒) 值
格式2:
set 键名 值 ex 过期时间(秒)
setex key3 10 1
set key3 1 ex 10
- 连续创建多个k-v
注意:添加的该值已经存在会覆盖用来的值
格式:
mset 键名1 键名2 ...
127.0.0.1:6379> mset key1 aaa key2 ccc key3 444
OK
- 连续获得多个k-v
格式:
mget 键名1 键名2 ...
127.0.0.1:6379> mget key1 key2 key3
1) "aaa"
2) "ccc"
3) "444"
List
- 从左侧加入一个元素
格式:
lpush 链名 值
127.0.0.1:6379> LPUSH list aaa ##返回1表示该值是该链中的第一个元素,在最下面
(integer) 1
127.0.0.1:6379> LPUSH list bbb
(integer) 2
127.0.0.1:6379> LPUSH list ddd
(integer) 3
- 查看链值
格式:
lrange 链名 初始下标 最后下标
127.0.0.1:6379> LRANGE list 0 -1 ##下标0表示第一个值 -1表示最后一个值
1) "ddd"
2) "bbb"
3) "aaa"
- 从上到下取出值
格式:
lpop 链名
127.0.0.1:6379> lpop list
"ddd"
- 从下到上插入值
格式:
rpush 链名 值
127.0.0.1:6379> RPUSH list 222
(integer) 3
- 从下到上取出值
格式:
rpop 链名
127.0.0.1:6379> RPOP list
"222"
- 在某个值上面插入值
格式:
linsert 键名 before 某个值 插入的值
127.0.0.1:6379> LRANGE list 0 -1
1) "bbb"
2) "aaa"
127.0.0.1:6379> LINSERT list before aaa zzz ##在aaa上面插入zzz
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "bbb"
2) "zzz"
3) "aaa"
- 在某个值下面插入值
格式:
linsert 键名 after 某个值 插入的值
127.0.0.1:6379> linsert list after aaa ccc ##在aaa下面插入ccc
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "bbb"
2) "zzz"
3) "aaa"
4) "ccc"
- 指定修改某个值
格式:
lset 键名 下标 修改的值
127.0.0.1:6379> LRANGE list 0 -1
1) "bbb"
2) "zzz"
3) "aaa"
4) "ccc"
127.0.0.1:6379> lset list 0 2bb ##0表示第一个值,即最上面的值
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "2bb"
2) "zzz"
3) "aaa"
4) "ccc"
- 查看链中某个值
格式:
lindex 键名 下标
127.0.0.1:6379> LINDEX list 1
"zzz"
- 查看链中共有多少个值
格式:
llen 键名
127.0.0.1:6379> llen list
(integer) 4
set
- 添加元素给集合
格式:
sadd 集合名 元素值 ...
127.0.0.1:6379> SADD set1 aaa
(integer) 1
- 查看集合中所有的元素
格式:
smembers 集合名
127.0.0.1:6379> SMEMBERS set1
1) "aaa"
2) "b"
3) "c"
4) "a"
- 删除元素
格式:
srem 集合名 删除的元素值
127.0.0.1:6379> SREM set1 b
(integer) 1
127.0.0.1:6379> SMEMBERS set1
1) "aaa"
2) "c"
3) "a"
- 随机取出几个元素,并删除
格式:
spop 集合名 [取出的个数]
127.0.0.1:6379> SPOP set1
"a"
127.0.0.1:6379> SMEMBERS set1
1) "aaa"
2) "c"
127.0.0.1:6379> SPOP set1 2
1) "aaa"
2) "c"
127.0.0.1:6379> SMEMBERS set1
(empty list or set)
- 随机取出几个元素,不会删除
格式:
srandmember 集合名 [取出的个数]
127.0.0.1:6379> SRANDMEMBER set1 2
1) "aaa"
2) "ccc"
127.0.0.1:6379> SMEMBERS set1
1) "bbb"
2) "aaa"
3) "ccc"
- 求差集
格式:
sdiff 集合1 集合2
(以集合1为标准)
127.0.0.1:6379> SMEMBERS set1
1) "bbb"
2) "aaa"
3) "ccc"
127.0.0.1:6379> SMEMBERS set2
1) "bbb"
2) "111"
3) "ccc"
4) "222"
127.0.0.1:6379> SDIFF set1 set2
1) "aaa"
127.0.0.1:6379> SDIFF set2 set1
1) "111"
2) "222"
- 求差集并存储到为新集合
格式:
sdiffstore 新集合 集合1 集合2
(以集合1为标准)
127.0.0.1:6379> SDIFFSTORE set3 set1 set2
(integer) 1
127.0.0.1:6379> SMEMBERS set3
1) "aaa"
- 求交集
格式:
sinter 集合1 集合2
127.0.0.1:6379> SINTER set1 set2
1) "bbb"
2) "ccc"
- 求交集并存储到为新集合
格式:
sinterstore 新集合 集合1 集合2
127.0.0.1:6379> SINTERSTORE set4 set1 set2
(integer) 2
127.0.0.1:6379> SMEMBERS set4
1) "bbb"
2) "ccc"
- 求并集
格式:
sunion 集合1 集合2
127.0.0.1:6379> SUNION set1 set2
1) "111"
2) "ccc"
3) "bbb"
4) "aaa"
5) "222"
- 求并集并存储到为新集合
格式:
sunionstore 新集合 集合1 集合2
127.0.0.1:6379> SUNIONSTORE set5 set1 set2
(integer) 5
127.0.0.1:6379> SMEMBERS set5
1) "111"
2) "ccc"
3) "bbb"
4) "aaa"
5) "222"
- 判断元素是否属于某个集合
格式:
sismember 集合名 判断的元素
127.0.0.1:6379> SMEMBERS set1
1) "bbb"
2) "aaa"
3) "ccc"
127.0.0.1:6379> SISMEMBER set1 111 ##0表示不属于 1表示属于该集合
(integer) 0
127.0.0.1:6379> SISMEMBER set1 ccc
(integer) 1
Sorted Set
Sorted Set
- 添加带权重的元素给集合
格式:
zadd 集合名 权重1 元素1 ...
127.0.0.1:6379> ZADD zset1 11 zyj1 22 zyj2 33 zyj3
(integer) 3
- 查看有序集合
格式:
zrange 集合名 初始下标 最后下标
127.0.0.1:6379> ZRANGE zset1 0 -1 ##下标0表示第一个值 -1表示最后一个值 元素从小到大排序
1) "zyj1"
2) "zyj2"
3) "zyj3"
- 删除元素
格式:
zrem 集合名 删除的元素值
127.0.0.1:6379> ZREM zset1 zyj2
(integer) 1
127.0.0.1:6379> ZRANGE zset1 0 -1
1) "zyj1"
2) "zyj3"
- 查看元素的索引值(下标)
格式:
zrank 集合名 查看的元素值
127.0.0.1:6379> ZRANGE zset1 0 -1
1) "zyj4"
2) "zyj1"
3) "zyj5"
4) "zyj3"
127.0.0.1:6379> ZRANK zset1 zyj4
(integer) 0
127.0.0.1:6379> ZRANK zset1 zyj1
(integer) 1
- 反序查看元素的索引值(下标)
格式:
zrevrank 集合名 查看的元素值
127.0.0.1:6379> ZRANGE zset1 0 -1
1) "zyj4"
2) "zyj1"
3) "zyj5"
4) "zyj3"
127.0.0.1:6379> ZREVRANK zset1 zyj4
(integer) 3
127.0.0.1:6379> ZREVRANK zset1 zyj1
(integer) 2
- 反序显示所有元素,可带分值
格式:
zrevrange 集合名 初始下标 最后下标
127.0.0.1:6379> ZREVRANGE zset1 0 -1 withscores
1) "zyj3"
2) "33"
3) "zyj5"
4) "15"
5) "zyj1"
6) "11"
7) "zyj4"
8) "1"
- 查看有序集合中共有多少个元素
格式:
zcard 集合名
127.0.0.1:6379> ZCARD zset1
(integer) 4
- 查看某个权重范围有多个元素
格式:
zcount 集合名 初始权重 结束权重
127.0.0.1:6379> ZCOUNT zset1 10 20 ##10-20的权重内有两个元素
(integer) 2
- 查看某个权重范围的元素值,可带分值
格式:
zrangebyscore 集合名 初始权重 结束权重
127.0.0.1:6379> ZRANGEBYSCORE zset1 10 20
1) "zyj1"
2) "zyj5"
127.0.0.1:6379> ZRANGEBYSCORE zset1 10 20 withscores
1) "zyj1"
2) "11"
3) "zyj5"
4) "15"
- 删除某个权重范围的元素值
格式:
zremrangebyscore 集合名 初始权重 结束权重
127.0.0.1:6379> ZREMRANGEBYSCORE zset1 10 20
(integer) 2
127.0.0.1:6379> ZRANGEBYSCORE zset1 10 20
(empty list or set)
- 删除某个索引范围的元素值
格式:
zremrangebyrank 集合名 初始下标 最后下标
127.0.0.1:6379> ZRANGE zset1 0 -1
1) "zyj4"
2) "zyj3"
127.0.0.1:6379> ZREMRANGEBYRANK zset1 0 2 ##删除索引第一个到第三个的元素
(integer) 2
Hash
- 添加hash数据
格式:
hset hash表名 键名 值
127.0.0.1:6379> HSET hash2 name zyj
(integer) 1
127.0.0.1:6379> HSET hash2 age 26
(integer) 1
127.0.0.1:6379> HSET hash2 job it
(integer) 1
- 查看整个hash表
格式:
hgetall hash表名
127.0.0.1:6379> HGETALL hash2**
1) "name"
2) "zyj"
3) "age"
4) "26"
5) "job"
6) "it"
- 查看hash表中的某个数据
格式:
hget hash表名 键名
127.0.0.1:6379> HGET hash2 job
"it"
- 添加多个hash数据
格式:
hmset hash表名 键名1 值1 ...
127.0.0.1:6379> HMSET hash3 name li age 20 job worker
OK
- 查看hash表中的多个数据
格式:
hmget hash表名 键名1 ...
127.0.0.1:6379> HMGET hash3 name job
1) "li"
2) "worker"
- 删除指定的键值
格式:
hdel hash表名 键名1 ...
127.0.0.1:6379> HDEL hash3 name ##删除name和对应的值
(integer) 1
127.0.0.1:6379> HGETALL hash3
1) "age"
2) "20"
3) "job"
4) "worker"
- 查看表中所有的键名
格式:
hkeys hash表名
127.0.0.1:6379> HKEYS hash2
1) "name"
2) "age"
3) "job"
- 查看表中所有的值
格式:
hvals hash表名
127.0.0.1:6379> HVALS hash2
1) "zyj"
2) "26"
3) "it"
- 查看表中总的k-v个数
格式:
hlen hash表名
127.0.0.1:6379> HLEN hash2 ##共有3个k-v段
(integer) 3
五、redis操作键值
- 查看所有建
格式:
keys *
127.0.0.1:6379> KEYS *
1) "key3"
2) "set2"
3) "key2"
4) "k3"
5) "set5"
6) "set3"
7) "k2"
8) "sset1"
9) "hash1"
10) "set4"
11) "hash3"
12) "k1"
13) "key1"
14) "hash2"
15) "set1"
16) "list1"
- 支持模糊匹配
127.0.0.1:6379> KEYS set*
1) "set2"
2) "set5"
3) "set3"
4) "set4"
5) "set1"
- 判断某个键是否存在
格式:
exists 键名
127.0.0.1:6379> EXISTS set10 ##0表示不存在 1表示存在
(integer) 0
127.0.0.1:6379> EXISTS set5
(integer) 1
- 删除指定键
格式:
del 键名
127.0.0.1:6379> DEL set5
(integer) 1
127.0.0.1:6379> get set5
(nil)
- 给某个建设置过期时间
格式:expire 键名 过期时间
127.0.0.1:6379> EXPIRE set4 10
(integer) 1
- 查看键的过期时间
格式:ttl 键名
127.0.0.1:6379> EXPIRE set3 100
(integer) 1
127.0.0.1:6379> TTL set3 ##92表示还有92s过期
(integer) 92
127.0.0.1:6379> ttl set4 ##-2表示该键值不存在了
(integer) -2
127.0.0.1:6379> ttl set2 ##-1表示该键值存在没有设置过期时间
(integer) -1
- 取消过期时间
格式:
persist 键名
127.0.0.1:6379> EXPIRE key3 1000 ##设置过期时间1000s
(integer) 1
127.0.0.1:6379> TTL key3 ##查看还有992s
(integer) 992
127.0.0.1:6379> PERSIST key3 ##取消过期时间
(integer) 1
127.0.0.1:6379> TTL key3 ##没有过期时间
(integer) -1
- 随机返回一个键
格式:
randomkey
127.0.0.1:6379> RANDOMKEY
"key1"
127.0.0.1:6379> RANDOMKEY
"k1"
- 重命名键名字
格式:
rename 旧键名 新键名
127.0.0.1:6379[1]> RENAME set1 set_new ##重命名
OK
127.0.0.1:6379[1]> KEYS *
1) "set_new"
- 返回建的类型
格式:
type 键名
127.0.0.1:6379> TYPE hash1
hash
127.0.0.1:6379> TYPE sset1
zset
127.0.0.1:6379> TYPE set2
set
- 选择进入库
- Redis自带有16个库,从0-15
格式:
select 库下标
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> KEYS *
(empty list or set)
- 移动键到其他库里
格式:
move 键名 库下标
127.0.0.1:6379> MOVE set1 1 ##把set1移动到第二个库中
(integer) 1
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> KEYS *
1) "set1"
- 返回当前数据库中键的个数
格式:
dbsize
127.0.0.1:6379> DBSIZE
(integer) 12
- 清空当前库中的键
格式:
flushdb
127.0.0.1:6379[1]> FLUSHDB
OK
127.0.0.1:6379[1]> KEYS *
(empty list or set)
- 清空所有库中的键
格式:
flushall
127.0.0.1:6379[1]> FLUSHALL
OK
- 保存数据到rdb文件中
格式:
save
127.0.0.1:6379> SAVE
OK
- 后台保存数据
格式:
bgsave
127.0.0.1:6379> BGSAVE
Background saving started
- 返回redis数据库状态信息
格式:
info
127.0.0.1:6379> INFO
# Server
redis_version:4.0.11
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c32f906a72ededb
redis_mode:standalone
os:Linux 3.10.0-693.el7.x86_64 x86_64
arch_bits:64
- 获得所有配置参数
格式:
config get *
127.0.0.1:6379> CONFIG GET *
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) ""
5) "masterauth"
6) ""
- 支持模糊匹配
127.0.0.1:6379> CONFIG GET log*
1) "logfile"
2) "/var/log/redis.log"
3) "loglevel"
4) "notice"
- 更改配置参数
格式:
config set 参数名 值
127.0.0.1:6379> CONFIG GET timeout
1) "timeout"
2) "0"
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"
六、redis安全设置
由于redis是以root用户登录的 而且redis默认是监听全文IP的。黑客可以轻易登录redis服务器后可以把他的公钥通过dir/dump.rdb来存放到/ssh/.authorized_kyes下来ssh服务器。
- 修改配置文件中的相关安全设置
[root@zyj02 ~]# vim /etc/redis.conf
修改内容如下:
bind 192.168.80.101 127.0.0.1 ##修改监听IP,多个IP用空格分开
port 9736 ##修改监听端口
requirepass 38003800 ##设置登录密码,密码为38003800,生产环境请设置尽量复制 这里只是测试
- 重启redis服务
[root@zyj02 ~]# killall redis-server
[root@zyj02 ~]# redis-server /etc/redis.conf
- 使用密码登录redis
格式:
redis-cli -a 密码
[root@zyj02 ~]# redis-cli -a '38003800'
Warning: Using a password with '-a' option on the command line interface may not be safe.
- config命令设置别名
[root@zyj02 ~]# vim /etc/redis.conf
修改内容如下:
rename-command CONFIG zyj ##用zyj来别名config
127.0.0.1:6379> zyj get *
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) "38003800"
- 禁止config命令
[root@zyj02 ~]# vim /etc/redis.conf
修改内容如下:
rename-command CONFIG ""
登陆测试:
127.0.0.1:6379> CONFIG GET *
(error) ERR unknown command `CONFIG`, with args beginning with: `GET`, `*`,
七、redis慢查询日志
- reids和MySQL一样也有慢查询日志,并在配置文件下定义。
[root@aming-02 ~]# vim /etc/redis.conf
修改内容如下:
slowlog-log-slower-than 10000 ##单位ms,表示慢于10000ms则记录日志,10000ms等于0.01s
slowlog-max-len 128 ## 定义日志长度,表示最多存128条日志
-
由于redis的数据是内在于内存中,因此只能通过命令行的查看慢查询日志
-
列出所有的慢查询日志
格式:slowlog get
[root@aming-02 ~]# redis-cli
127.0.0.1:6379> SLOWLOG get
1) 1) (integer) 2
2) (integer) 1534796516
3) (integer) 105
4) 1) "KEYS"
2) "k3"
5) "127.0.0.1:50496"
6) ""
2) 1) (integer) 1
2) (integer) 1534796511
3) (integer) 37
4) 1) "KEYS"
2) "*"
5) "127.0.0.1:50496"
6) ""
3) 1) (integer) 0
2) (integer) 1534796505
3) (integer) 301
4) 1) "COMMAND"
5) "127.0.0.1:50496"
6) ""
##这里有3条命令 第一条是登录 第二条是keys * 第三条是keys k3
127.0.0.1:6379> SLOWLOG get 2 ##2表示显示最新的两条慢查询日志
1) 1) (integer) 3
2) (integer) 1534796526
3) (integer) 35
4) 1) "SLOWLOG"
2) "get"
5) "127.0.0.1:50496"
6) ""
2) 1) (integer) 2
2) (integer) 1534796516
3) (integer) 105
4) 1) "KEYS"
2) "k3"
5) "127.0.0.1:50496"
6) ""
- 列出当前慢日志的条数
格式:slowlog len
127.0.0.1:6379> SLOWLOG len ##当前有5条慢日志
(integer) 5
八、php安装redis扩展模块
-
与memcache一样,redis要和php打交道就需要下载redis的模块
-
步骤
- 进入src目录并下载解压redis
[root@aming-01 ~]# cd /usr/local/src/
[root@aming-01 src]# wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip
[root@aming-01 src]# unzip phpredis.zip
- 也可以去官方网站下载redis模块https://codeload.github.com/phpredis/phpredis/zip/develop
- 进入phpredis-develo目录里并生成configure
[root@aming-01 src]# cd phpredis-develop/
[root@aming-01 phpredis-develop]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.
##和安装memcache一样这里少了autoconf
- 安装autoconf再次生成configure
[root@aming-01 phpredis-develop]# yum install -y autoconf
[root@aming-01 phpredis-develop]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303
- 初始化
[root@aming-01 phpredis-develop]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
- 编译 安装
[root@aming-01 phpredis-develop]# make
[root@aming-01 phpredis-develop]# make install
- 加载扩张模块
[root@aming-01 phpredis-develop]# vim /usr/local/php-fpm/etc/php.ini
添加内容如下:
extension=redis.so
- 重启php-fpm服务
[root@aming-01 phpredis-develop]# service php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm done
- 查看php-fpm是否加载redis模块
[root@aminglinux01 ~]# /usr/local/php7/bin/php -m
[PHP Modules]
redis
九、PHP中使用redis – 存储session
- redis和memcache一样 存储session也有三种办法
- 编辑php.ini文件
[root@aming-01 redis-4.0.11]# vim /usr/local/php-fpm/etc/php.ini
添加如下内容:
session.save_handler = "redis"
session.save_path = "tcp://127.0.0.1:6379"
- 编辑httpd.cong相应的配置文件
[root@aming-02 src]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
php_value session.save_handler "redis"
php_value session.save_path "tcp://127.0.0.1:6379"
- 编辑php相应的pool
[root@aming-02 src]# vim /usr/local/php-fpm/etc/php-fpm.d/test1.conf
php_value[session.save_handler] = redis
php_value[session.save_path] = "tcp://127.0.0.1:6379"
##注意:由于我定义了监听了127.0.0.1 因此这里tcp的ip地址也有写127.0.0.1 否则失败
- 测试
- 下载一个php测试页面看redis是否存储了session
- 代码内容在
https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/21NOSQL/session.php
[root@aming-01 ~]# wget http://study.lishiming.net/.mem_se.txt
[root@aming-01 ~]# cp .mem_se.txt /var/www/test1/index.html
3.访问几次测试页面 最后一段为键名
[root@aming-02 src]# curl localhost
1534809166<br><br>1534809166<br><br>m748s8primu6pu3b62pn4ejc35
4.进入redis
[root@aming-02 src]# redis-cli
127.0.0.1:6379> KEYS *
1) "k2"
2) "set2"
3) "list1"
4) "sset1"
5) "hash2"
6) "key1"
7) "PHPREDIS_SESSION:m748s8primu6pu3b62pn4ejc35"
127.0.0.1:6379> get PHPREDIS_SESSION:m748s8primu6pu3b62pn4ejc35
"TEST|i:1534809166;TEST3|i:1534809166;"
10、redis主从配置
-
这里我们在同一台服务器上配置Redis主从,主继续使用6379端口,从使用6380端口,Redis主从只需要配置从机器上配置文件。当建立了Redis主从后 Redis数据就自动同步,不需要提前同步数据。
-
步骤
- 拷贝配置文件并改名Redis2
[root@aming-01 ~]# cp /etc/redis.conf /etc/redis2.conf
##修改redis2配置文件
[root@aming-01 ~]# vim /etc/redis2.conf
##修改下面参数
port 6380
pidfile /var/run/redis_6380.pid
dir /data/redis2
logfile "/var/log/redis2.log"
##添加下面参数
slaveof 127.0.0.1 6379 ##slaveof 主IP 端口
##如果主上设置了密码 从需要添加下面参数
maseterauth 38003800 ## maseterauth 主的密码
##默认设置从是只读的
slave-read-only yes
- 创建从的数据目录
[root@aming-01 ~]# mkdir /data/redis2
##启动Redis服务
[root@aming-01 ~]# redis-server /etc/redis.conf
[root@aming-01 ~]# redis-server /etc/redis2.conf
- 测试
- 在主上添加数据 回去从上看是否同步数据
[root@aming-01 ~]# redis-cli
127.0.0.1:6379> set test1 hello
OK
127.0.0.1:6379> KEYS *
1) "test1"
[root@aming-01 ~]# redis-cli -h 127.0.0.1 -p 6380
127.0.0.1:6380> KEYS *
1) "test1"
11、redis集群介绍
- redis集群是分布式的,写入的数据并不在同一台机器上,因此每台机器上的数据并不一致。
- Redis集群上的所有节点都是一主一从(可以是多个从),其中从不提供服务,仅作为备用。
- 不支持同时处理多个键(如mset/mget),因为redis需要把键均匀分布在各个节点上,并发量很高的情况下同时创建键值会降低性能并导致不可预测的行为。
- 支持在线增加、删除节点。客户端可以连任何一个主节点进行读写。
12、redis集群搭建配置(4.0需要ruby)
- 场景设置:
两台机器,分别开启三个Redis服务(端口)
aming-01 192.168.80.102
aming-02 192.168.80.103
aming-01机器上三个端口7000,7002,7004,全部为主
aming-02机器上三个端口7001,7003,7005,全部为从
-
两台机器上都要编译安装redis,然后编辑并复制3个不同的redis.conf,分别设置不同的端口号、dir等参数,还需要增加cluster相关参数,然后分别启动6个redis服务
-
具体redis配置文件大家到:
https://coding.net/u/aminglinux/p/yuanke_centos7/git/tree/master/21NOSQL
-
准备工作
- 在aming-01机器上,编辑7000 7002 7004的配置文件
[root@aming-01 ~]# vim /etc/redis_7000.conf
内容如下:
port 7000
bind 192.168.80.102
daemonize yes
pidfile /var/run/redis_7000.pid
dir /data/redis_data/7000
cluster-enabled yes ##表示开启集群
cluster-config-file nodes_7000.conf ##集群的配置文件 会自动生成
cluster-node-timeout 10100
appendonly yes
[root@aming-01 ~]# vim /etc/redis_7002.conf
内容如下:
port 7002
bind 192.168.80.102
daemonize yes
pidfile /var/run/redis_7002.pid
dir /data/redis_data/7002
cluster-enabled yes
cluster-config-file nodes_7002.conf
cluster-node-timeout 10100
appendonly yes
[root@aming-01 ~]# vim /etc/redis_7004.conf
内容如下:
port 7004
bind 192.168.80.102
daemonize yes
pidfile /var/run/redis_7004.pid
dir /data/redis_data/7004
cluster-enabled yes
cluster-config-file nodes_7004.conf
cluster-node-timeout 10100
appendonly yes
- 在aming-01上创建对应的数据目录
[root@aming-01 ~]# mkdir /data/redis_data
[root@aming-01 ~]# mkdir /data/redis_data/{7000,7002,7004}
- 在aming-01上启动Redis服务
[root@aming-01 ~]# redis-server /etc/redis_7000.conf
[root@aming-01 ~]# redis-server /etc/redis_7002.conf
[root@aming-01 ~]# redis-server /etc/redis_7004.conf
- 在aming-02机器上,编辑7001 7003 7005的配置文件
[root@aming-02 ~]# vim /etc/redis_7001.conf
内容如下:
port 7001
bind 192.168.80.103
daemonize yes
pidfile /var/run/redis_7001.pid
dir /data/redis_data/7001
cluster-enabled yes
cluster-config-file nodes_7001.conf
cluster-node-timeout 10100
appendonly yes
[root@aming-02 ~]# vim /etc/redis_7003.conf
内容如下:
port 7003
bind 192.168.80.103
daemonize yes
pidfile /var/run/redis_7003.pid
dir /data/redis_data/7003
cluster-enabled yes
cluster-config-file nodes_7003.conf
cluster-node-timeout 10100
appendonly yes
[root@aming-02 ~]# vim /etc/redis_7005.conf
内容如下:
port 7005
bind 192.168.80.103
daemonize yes
pidfile /var/run/redis_7005.pid
dir /data/redis_data/7005
cluster-enabled yes
cluster-config-file nodes_7005.conf
cluster-node-timeout 10100
appendonly yes
- 在aming-02上,创建对应的数据目录
[root@aming-02 ~]# mkdir /data/redis_data/
[root@aming-02 ~]# mkdir /data/redis_data/{7001,7003,7005}
- 启动Redis服务
[root@aming-02 ~]# redis-server /etc/redis_7001.conf
[root@aming-02 ~]# redis-server /etc/redis_7003.conf
[root@aming-02 ~]# redis-server /etc/redis_7005.conf
- 现在任意一台机器上安装Ruby2.2 由于yum上的Ruby只有2.0版本,而redis cluster支持ruby2.2的。因此需要安装ruby。这里是把ruby的源码包制作成rpm包来安装ruby的 ,也可以直接编译安装源码包来安装ruby。
- 步骤
- 下载对应的包
[root@aming-01 ~]# yum -y groupinstall "Development Tools"
[root@aming-01 ~]# yum -y install gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-deve
- 进入root目录下
[root@aming-01 ~]# cd /root/
- 创建目录
[root@aming-01 ~]# mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
- 下载源码包和spec文件到rpmbuild/SOURCES目录下
[root@aming-01 ~]# wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P rpmbuild/SOURCES
[root@aming-01 ~]# wget https://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P rpmbuild/SPECS
- 制作ruby的rpm包
[root@aming-01 ~]# rpmbuild -bb rpmbuild/SPECS/ruby22x.spec
- yum安装本地rpm包
[root@aming-01 ~]# yum -y localinstall rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
- 下载redis-trib.rb并拷贝到bin目录下
[root@aming-01 ~]# gem install redis
[root@aming-01 ~]# cp /usr/local/src/redis-4.0.11/src/redis-trib.rb /usr/bin/
- 使用redis-trib.rb命令建立集群
[root@aming-01 ~]# redis-trib.rb create --replicas 1 192.168.80.102:7000 192.168.80.102:7002 192.168.80.102:7004 192.168.80.103:7001 192.168.80.103:7003 192.168.80.103:7005
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
##看到两个OK表示已经集群创建成功
13、redis集群操作
-
可以连接任意一个节点来操作Redis集群
-
登录集群
格式:redis-cli -c -h IP -p 端口
[root@aming-01 x86_64]# redis-cli -c -h 192.168.80.102 -p 7000
`-h` 指定IP
`-c` 使用集群方式登录
`-p` 指定端口
- 查看集群状态
格式:redis-trib.rb check 任意节点IP:端口
[root@aming-01 x86_64]# redis-trib.rb check 192.168.80.102:7000
>>> Performing Cluster Check (using node 192.168.80.102:7000)
M: 2042a7a6231ea5b6eb42ca3a5bf02abb419126a0 192.168.80.102:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 41866d20d5f0d736b05abaea15d0e08b6bcd9350 192.168.80.103:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: 48f4abd0547a0c794c6905c2bd0a314f212b0042 192.168.80.103:7005
slots: (0 slots) slave
M: c66658b3eea43e01d49367a7f610055a6ec0d5bd 192.168.80.102:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 90c82e347f19415b3692c2cab5a671566573bbd9 192.168.80.102:7004
slots: (0 slots) slave
replicates 41866d20d5f0d736b05abaea15d0e08b6bcd9350
S: 28d00e5717a7eb28dc461c002e733dba94ac9a5e 192.168.80.103:7003
slots: (0 slots) slave
replicates c66658b3eea43e01d49367a7f610055a6ec0d5bd
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
-
前面命令都是进入集群后操作的
-
列出节点
格式:cluster ndes
192.168.80.102:7000> CLUSTER NODES
41866d20d5f0d736b05abaea15d0e08b6bcd9350 192.168.80.103:7001@17001 master - 0 1534940719663 4 connected 5461-10922
48f4abd0547a0c794c6905c2bd0a314f212b0042 192.168.80.103:7005@17005 slave 2042a7a6231ea5b6eb42ca3a5bf02abb419126a0 0 1534940715632 6 connected
c66658b3eea43e01d49367a7f610055a6ec0d5bd 192.168.80.102:7002@17002 master - 0 1534940718150 2 connected 10923-16383
90c82e347f19415b3692c2cab5a671566573bbd9 192.168.80.102:7004@17004 slave 41866d20d5f0d736b05abaea15d0e08b6bcd9350 0 1534940717645 4 connected
2042a7a6231ea5b6eb42ca3a5bf02abb419126a0 192.168.80.102:7000@17000 myself,master - 0 1534940715000 1 connected 0-5460
28d00e5717a7eb28dc461c002e733dba94ac9a5e 192.168.80.103:7003@17003 slave c66658b3eea43e01d49367a7f610055a6ec0d5bd 0 1534940718655 5 connected
7005 slave 2042a7a6231ea5b6eb42ca3a5bf02abb419126a0 2042a7a6231ea5b6eb42ca3a5bf02abb419126a0 表示7000的nodeIP,因此7005是7000的从
- 查看集群信息
格式:cluster info
192.168.80.102:7000> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1920
cluster_stats_messages_pong_sent:1271
cluster_stats_messages_fail_sent:4
cluster_stats_messages_sent:3195
cluster_stats_messages_ping_received:1271
cluster_stats_messages_pong_received:1372
cluster_stats_messages_fail_received:1
cluster_stats_messages_received:2644
- 添加新节点
格式:cluster meet 节点IP 端口
192.168.80.102:7000> CLUSTER MEET 192.168.80.102 7006
OK
192.168.80.102:7000> CLUSTER MEET 192.168.80.103 7007
OK
192.168.80.102:7000> CLUSTER NODES ##新添加的节点默认都是master
8b9e3db578088c156fc9733185423880e415a0da 192.168.80.103:7007@17007 master - 0 1534941780821 7 connected
bd436acd42955038a96b2bab9df2dcb70f347439 192.168.80.102:7006@17006 master - 0 1534941781000 0 connected
- 把当前节点设置为指定节点的从
格式:cluster replicater 主节点的node_id
[root@aming-01 x86_64]# redis-cli -c -h 192.168.80.103 -p 7007 ##进入7007的节点
192.168.80.103:7007> CLUSTER REPLICATE bd436acd42955038a96b2bab9df2dcb70f347439
OK ##指定为7006的node_id的从
192.168.80.103:7007> CLUSTER NODES
8b9e3db578088c156fc9733185423880e415a0da 192.168.80.103:7007@17007 myself,slave bd436acd42955038a96b2bab9df2dcb70f347439 0 1534941891000 7 connected
bd436acd42955038a96b2bab9df2dcb70f347439 192.168.80.102:7006@17006 master - 0 1534941893533 0 connected
- 移除节点
格式:cluster forget 移除节点node_id
192.168.80.103:7007> CLUSTER FORGET bd436acd42955038a96b2bab9df2dcb70f347439
(error) ERR Can't forget my master! ##不能移除为主的节点,可以把该节点设置为其他几点的从后再移除
192.168.80.103:7007> CLUSTER FORGET 8b9e3db578088c156fc9733185423880e415a0da
(error) ERR I tried hard but I can't forget myself... ##不能移除当前节点 ,可以登录其他节点再来移除
[root@aming-01 x86_64]# redis-cli -c -h 192.168.80.102 -p 7000 ##登录7000节点来移除7007节点
192.168.80.102:7000> CLUSTER FORGET 8b9e3db578088c156fc9733185423880e415a0da
OK
- 保存集群配置
格式:cluster saveconfig
192.168.80.102:7000> CLUSTER SAVECONFIG
OK ##默认保存到某个节点的数据目录下.config文件中