#第一步:安装 C 语言需要的 GCC 环境
yum install -y gcc-c++
yum install -y wget
#第二步:下载并解压缩 Redis 源码压缩包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar -zxf redis-5.0.5.tar.gz
#第三步:编译 Redis 源码,进入 redis-5.0.5 目录,执行编译命令
cd redis-5.0.5/src
make
#第四步:安装 Redis,需要通过 PREFIX 指定安装路径
mkdir /usr/redis -p
make install PREFIX=/usr/redis
#复制conf
cd ../
cp redis.conf /usr/redis/bin/
cp sentinel.conf /usr/redis/bin/
#修改redis.conf
vim redis.conf
#注释掉则不限于本机器访问
#bind 127.0.0.1
#no 允许外界访问
protected-mode no
#yes 守护进程后台启动
daemonize yes
#占用窗口启动 --不可以被远程访问
./redis-server
#关闭
control + c
#不占用窗口启动 --不可以被远程访问
./redis-server &
#守护进程后台启动 --可以被远程访问
./redis-server redis.conf
#守护进程后台启动关闭
./redis-cli shutdown
#查看进程
ps -ef |grep redis
root 7891 1977 0 17:14 pts/1 00:00:04 ./redis-server *:6379
#关闭进程
kill -9 7891
#客户端启动
./redis-cli -h 127.0.0.1 -p 6379
# 关闭centos的防火墙
#systemctl stop firewalld
# 设置centos防火墙不开机自启动
#systemctl disable firewalld.service
#监控
monitor
#查看所有key
keys *
#通过 info 命令可以查看关于持久化的信息
info
#RDB持久化save或bgsave
bgsave
#aof重写命令需先配置aof
bgrewriteaof
#查看类型
type key
#查看对象采用的编码方式
object encoding key
#获取 maxmemory
config get maxmemory
#设置maxmemory
config set maxmemory 50mb
#设置失效时间
127.0.0.1:6379> expire key 60
#查看过期时间 -1永久、-2失效
ttl key
#查看服务器状态信息
info
#删除
del key
#懒删除
UNLINK key1 key2
#集群的创建先主后从,数字为主从中从的个数
./redis-cli --cluster create 172.16.94.13:7010 172.16.94.13:7020 172.16.94.13:7031 172.16.94.13:7032 --cluster-replicas 1
#启动集群客户端
./redis-cli -h 127.0.0.1 -p 7022 -c
#集群扩容添加master前面是要添加的后面是集群中的任一个节点
./redis-cli --cluster add-node 172.16.94.13:7101 172.16.94.13:7022
#集群扩容添加master后重新分槽
./redis-cli --cluster reshard 172.16.94.13:7101
#集群扩容添加slave 7102,需指定主机id和port
./redis-cli --cluster add-node 172.16.94.13:7102 172.16.94.13:7101 --cluster-slave --cluster-master-id 7cedc3fccea9d4f155835fdd3ecf102306f6c4ff
#查看集群节点信息
cluster info
cluster nodes
#只从该节点读取数据
readonly
#删除集群节点
./redis-cli --cluster del-node 172.16.94.13:7101 7cedc3fccea9d4f155835fdd3ecf102306f6c4ff
Redis 是一个 Key-Value 的存储系统,使用 ANSI C 语言编写。
key 的类型是字符串、整数
value 的数据类型有:
常用的:string 字符串类型、list 列表类型、set 集合类型、sortedset(zset)有序集合类型、hash 类 型。
不常见的:bitmap 位图类型、geo 地理位置类型。
Redis5.0 新增一种:stream 类型
注意:Redis 中命令是忽略大小写,(set SET),key 是不忽略大小写的 (NAME name)
keys * 查看所有的 key
Redis 的 String 能表达 3 种值的类型:字符串、整数、浮点数 100.01 是个六位的串
常见操作命令如下表:
命令名称 | 命令描述 | |
---|---|---|
set | set key value | 赋值 |
get | get key | 取值 |
getset | getset key value | 取值并赋值 |
setnx | setnx key value | 当 key 不存在时才用赋值 set key value NX PX 3000 原子操作,px 设置毫秒数 |
append | append key value | 向尾部追加值 |
strlen | strlen key | 获取字符串长度 |
incr | incr key | 递增数字 |
incrby | incrby key increment | 增加指定的整数 |
decr | decr key | 递减数字 |
decrby | decrby key decrement | 减少指定的整数 |
命令操作演示
127.0.0.1:6379> set weather cloudy
OK
127.0.0.1:6379> get weather
"cloudy"
127.0.0.1:6379> getset weather sunny
"cloudy"
127.0.0.1:6379> setnx weather rainy #没有值则成功,有则失败
(integer) 0
127.0.0.1:6379> get weather
"sunny"
127.0.0.1:6379> setnx sky blue
(integer) 1
127.0.0.1:6379> get sky
"blue"
127.0.0.1:6379> set sky white nx px 20000 #没有值则成功,有则失败,过期时间20s
(nil)
127.0.0.1:6379> set cloud white nx px 20000
OK
127.0.0.1:6379> set cloud white1 nx px 20000
(nil)
127.0.0.1:6379> set cloud white1 nx px 20000
OK
127.0.0.1:6379> get cloud
"white1"
127.0.0.1:6379> append tree green
(integer) 5
127.0.0.1:6379> get tree
"green"
127.0.0.1:6379> strlen tree
(integer) 5
127.0.0.1:6379> incr wind
(integer) 1
127.0.0.1:6379> incr wind
(integer) 2
127.0.0.1:6379> incrby wind 10
(integer) 12
127.0.0.1:6379> decr wind
(integer) 11
127.0.0.1:6379> decrby wind 5
(integer) 6
应用场景
1、key 和命令是字符串
2、普通的赋值
3、incr 用于乐观锁 incr:递增数字,可用于实现乐观锁 watch(事务)
4、setnx 用于分布式锁 当 value 不存在时采用赋值,可用于实现分布式锁
list 列表类型可以存储有序、可重复的元素
获取头部或尾部附近的记录是极快的
list 的元素个数最多为 2^32-1 个(40 亿)
常见操作命令如下表:
命令名称 | 命令格式 | 描述 |
---|---|---|
lpush | lpush key v1 v2 v3 … | 从左侧插入列表 |
lpop | lpop key | 从列表左侧取出 |
rpush | rpush key v1 v2 v3 … | 从右侧插入列表 |
rpop | rpop key | 从列表右侧取出 |
lpushx | lpushx key value | 将值插入到列表头部 |
rpushx | rpushx key value | 将值插入到列表尾部 |
blpop | blpop key timeout | 从列表左侧取出,当列表为空时阻塞,可以设置最大阻塞时 间,单位为秒 |
brpop | blpop key timeout | 从列表右侧取出,当列表为空时阻塞,可以设置最大阻塞时 间,单位为秒 |
llen | llen key | 获得列表中元素个数 |
lindex | lindex key index | 获得列表中下标为 index 的元素 index 从 0 开始 |
lrange | lrange key start end | 返回列表中指定区间的元素,区间通过 start 和 end 指定 |
lrem | lrem key count value | 删除列表中与 value 相等的元素 当 count>0 时, lrem 会从列表左边开始删除;当 count<0 时, lrem 会从列表后边开始删除;当 count=0 时, lrem 删除所有值 为 value 的元素 |
lset | lset key index value | 将列表 index 位置的元素设置成 value 的值 |
ltrim | ltrim key start end | 对列表进行修剪,只保留 start 到 end 区间 |
rpoplpush | rpoplpush key1 key2 | 从 key1 列表右侧弹出并插入到 key2 列表左侧 |
brpoplpush | brpoplpush key1 key2 | 从 key1 列表右侧弹出并插入到 key2 列表左侧,会阻塞 |
linsert | linsert key BEFORE/AFTER pivot value | 将 value 插入到列表,且位于值 pivot 之前或之后 |
操作演示
127.0.0.1:6379> lpush list:my 1 2 3 4 5
(integer) 5
127.0.0.1:6379> lpop list:my
"5"
127.0.0.1:6379> lpop list:my
"4"
127.0.0.1:6379> rpush list:my 11 13 15
(integer) 6
127.0.0.1:6379> rpop list:my
"15"
127.0.0.1:6379> lrange list:my 0 3
1) "3"
2) "2"
3) "1"
4) "11"
127.0.0.1:6379> lpushx list:my f
(integer) 6
127.0.0.1:6379> lrange list:my 0 -1
1) "f"
2) "3"
3) "2"
4) "1"
5) "11"
6) "13"
127.0.0.1:6379> rpushx list:my l
(integer) 7
127.0.0.1:6379> lrange list:my 0 -1
1) "f"
2) "3"
3) "2"
4) "1"
5) "11"
6) "13"
7) "l"
127.0.0.1:6379> blpop list:my 20
1) "list:my"
2) "f"
127.0.0.1:6379> llen list:my
(integer) 6
127.0.0.1:6379> lindex list:my 3
"11"
127.0.0.1:6379> lrem list:my -1 11
(integer) 1
127.0.0.1:6379> lrange list:my 0 -1
1) "3"
2) "2"
3) "1"
4) "13"
5) "l"
127.0.0.1:6379> lset list:my 3 5
OK
127.0.0.1:6379> lrange list:my 0 -1
1) "3"
2) "2"
3) "1"
4) "5"
5) "l"
127.0.0.1:6379> ltrim list:my 1 3
OK
127.0.0.1:6379> lrange list:my 0 -1
1) "2"
2) "1"
3) "5"
127.0.0.1:6379> linsert list:my before 5 6
(integer) 4
127.0.0.1:6379> lrange list:my 0 -1
1) "2"
2) "1"
3) "6"
4) "5"
127.0.0.1:6379>
应用场景
1、作为栈或队列使用
列表有序可以作为栈和队列使用
2、可用于各种列表,比如用户列表、商品列表、评论列表等。
Set:无序、唯一元素
集合中最大的成员数为 2^32 - 1
常见操作命令
命令名称 | 命令格式 | 描述 |
---|---|---|
sadd | sadd key mem1 mem2 … | 为集合添加新成员 |
srem | srem key mem1 mem2 … | 删除集合中指定成员 |
smembers | smembers key | 获得集合中所有元素 |
spop | spop key | 返回集合中一个随机元素,并将该元素删除 |
srandmember | srandmember key | 返回集合中一个随机元素,不会删除该元素 |
scard | scard key | 获得集合中元素的数量 |
sismember | sismember key member | 判断元素是否在集合内 |
sinter | sinter key1 key2 key3 | 求多集合的交集 |
sdiff | sdiff key1 key2 key3 | 求多集合的差集 |
sunion | sunion key1 key2 key3 | 求多集合的并集 |
操作演示
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> smembers myset
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> srem myset a
(integer) 1
127.0.0.1:6379> spop myset
"c"
127.0.0.1:6379> srandmember myset
"b"
127.0.0.1:6379> scard myset
(integer) 1
127.0.0.1:6379> sismember b
(error) ERR wrong number of arguments for 'sismember' command
127.0.0.1:6379> sismember myset b
(integer) 1
127.0.0.1:6379> smembers myset
1) "b"
127.0.0.1:6379> sadd myset2 b c d
(integer) 3
127.0.0.1:6379> sinter myset myset2
1) "b"
127.0.0.1:6379> sdiff myset myset2
(empty list or set)
127.0.0.1:6379> sunion myset myset2
1) "b"
2) "c"
3) "d"
127.0.0.1:6379>
应用场景
适用于不能重复的且不需要顺序的数据结构
比如:关注的用户,还可以通过 spop 进行随机抽奖
SortedSet(ZSet) 有序集合: 元素本身是无序不重复的
每个元素关联一个分数(score)
可按分数排序,分数可重复
常见操作
命令名称 | 命令格式 | 描述 |
---|---|---|
zadd | zadd key score1 member1 score2 member2 … | 为有序集合添加新成员 |
zrem | zrem key mem1 mem2 … | 删除有序集合中指定成员 |
zcard | zcard key | 获得有序集合中的元素数量 |
zcount | zcount key min max | 返回集合中 score 值在[min,max]区间 的元素数量 |
zincrby | zincrby key increment member | 在集合的 member 分值上加 increment |
zscore | zscore key member | 获得集合中 member 的分值 |
zrank | zrank key member | 获得集合中 member 的排名(按分值从 小到大) |
zrevrank | zrevrank key member | 获得集合中 member 的排名(按分值从 大到小) |
zrange | zrange key start end | 获得集合中指定区间成员,按分数递增 排序 |
zrevrange | zrevrange key start end | 获得集合中指定区间成员,按分数递减 排序 |
操作演示
127.0.0.1:6379> zadd myscore 90 english 80 chemistry 70 geography
(integer) 3
127.0.0.1:6379> zadd yourscore 91 english 81 chemistry 71 geography
(integer) 3
127.0.0.1:6379> zadd hisscore 92 english 82 chemistry 72 geography
(integer) 3
127.0.0.1:6379> zrank myscore english
(integer) 2
127.0.0.1:6379> zrevrank myscore english
(integer) 0
127.0.0.1:6379> zrange yourscore 0 -1
1) "geography"
2) "chemistry"
3) "english"
127.0.0.1:6379> zrevrange yourscore 0 -1
1) "english"
2) "chemistry"
3) "geography"
127.0.0.1:6379> zscore myscore english
"90"
127.0.0.1:6379> zincrby myscore 10 english
"100"
127.0.0.1:6379> zcount myscore 80 100
(integer) 2
127.0.0.1:6379> zcard myscore
(integer) 3
127.0.0.1:6379> zrem myscore english
(integer) 1
127.0.0.1:6379> zrange myscore 0 -1
1) "geography"
2) "chemistry"
127.0.0.1:6379>
应用场景
由于可以按照分值排序,所以适用于各种排行榜。比如:点击排行榜、销量排行榜、关注排行榜等。
hash 类型(散列表)
Redis hash 是一个 string 类型的 field 和 value 的映射表,它提供了字段和字段值的映射。
每个 hash 可以存储 2^32 - 1 键值对(40 多亿)。
Redis hash 是一个 string 类型的 field 和 value 的映射表,它提供了字段和字段值的映射。
每个 hash 可以存储 2^32 - 1 键值对(40 多亿)。
常见操作命令
命令名称 | 命令格式 | 描述 |
---|---|---|
hset | hset key field value | 赋值,不区别新增或修改 |
hmset | hmset key field1 value1 field2 value2 | 批量赋值 |
hsetnx | hsetnx key field value | 赋值,如果 filed 存在则不操作 |
hexists | hexists key filed | 查看某个 field 是否存在 |
hget | hget key field | 获取一个字段值 |
hmget | hmget key field1 field2 … | 获取多个字段值 |
hgetall | hgetall key | |
hdel | hdel key field1 field2… | 删除指定字段 |
hincrby | hincrby key field increment | 指定字段自增 increment |
hlen | hlen key | 获得字段数量 |
应用场景
对象的存储 ,表数据的映射
操作演示
127.0.0.1:6379> hmset user:001 username xiaozhi password 1234 age 10 sex m
OK
127.0.0.1:6379> hset user:002 usename xiaoxia
(integer) 1
127.0.0.1:6379> hsetnx user:002 username xiaoxia2
(integer) 1
127.0.0.1:6379> hexists user:001 username
(integer) 1
127.0.0.1:6379> hget user:001 username
"xiaozhi"
127.0.0.1:6379> hmget user:001 username
1) "xiaozhi"
127.0.0.1:6379> hmget user:001 username password age
1) "xiaozhi"
2) "1234"
3) "10"
127.0.0.1:6379> hgetall user:001
1) "username"
2) "xiaozhi"
3) "password"
4) "1234"
5) "age"
6) "10"
7) "sex"
8) "m"
127.0.0.1:6379> hdel user:001 sex
(integer) 1
127.0.0.1:6379> hincrby user:001 password 10
(integer) 1244
127.0.0.1:6379> hlen user:001
(integer) 3
127.0.0.1:6379>
bitmap 是进行位操作的
通过一个 bit 位来表示某个元素对应的值或者状态,其中的 key 就是对应元素本身。
bitmap 本身会极大的节省储存空间。
应用场景
1、用户每月签到,用户 id 为 key , 日期作为偏移量 1 表示签到
2、统计活跃用户, 日期为 key,用户 id 为偏移量 1 表示活跃
3、查询用户在线状态, 日期为 key,用户 id 为偏移量 1 表示在线
常见操作命令
命令名 称 | 命令格式 | 描述 |
---|---|---|
setbit | setbit key offset value | 设置 key 在 offset 处的 bit 值(只能是 0 或者 1)。 |
getbit | getbit key offset | 获得 key 在 offset 处的 bit 值 |
bitcount | bitcount key | 获得 key 的 bit 位为 1 的个数 |
bitpos | bitpos key value | 返回第一个被设置为 bit 值的索引值 |
bitop | bitop and[or/xor/not] destkey key [key …] | 对多个 key 进行逻辑运算后存入 destkey 中 |
操作演示
127.0.0.1:6379> setbit user:sign:1000 20200101 1 #id为1000的用户20200101签到
(integer) 0
127.0.0.1:6379> setbit user:sign:1000 20200103 1 #id为1000的用户20200103签到
(integer) 0
127.0.0.1:6379> getbit user:sign:1000 20200101 #获得id为1000的用户20200101签到状态 1 表示签到
(integer) 1
127.0.0.1:6379> getbit user:sign:1000 20200102 #获得id为1000的用户20200102签到状态 0表示未签到
(integer) 0
127.0.0.1:6379> bitcount user:sign:1000 # 获得id为1000的用户签到次数
(integer) 2
127.0.0.1:6379> bitpos user:sign:1000 1 #id为1000的用户第一次签到的日期
(integer) 20200101
127.0.0.1:6379> setbit 20200201 1000 1 #20200201的1000号用户上线
(integer) 0
127.0.0.1:6379> setbit 20200202 1001 1 #20200202的1000号用户上线
(integer) 0
127.0.0.1:6379> setbit 20200201 1002 1 #20200201的1002号用户上线
(integer) 0
127.0.0.1:6379> bitcount 20200201 #20200201的上线用户有2个
(integer) 2
127.0.0.1:6379> bitop or desk1 20200201 20200202 #合并20200201的用户和20200202上线 了的用户
(integer) 126
127.0.0.1:6379> bitcount desk1 #统计20200201和20200202都上线的用 户个数
(integer) 3
geo 是 Redis 用来处理位置信息的。在 Redis3.2 中正式使用。主要是利用了 Z 阶曲线、Base32 编码和 geohash 算法
**Geohash 是一种地理位置信息编码方法。 经过 geohash 映射后,地球上任意位置的经纬度坐标可以表示成一个较短的字符串。可以方便的存储在数据 库中,附在邮件上,以及方便的使用在其他服务中。**以北京的坐标举例,[39.928167,116.389550]可以 转换成 wx4g0s8q3jf9 。
应用场景
1、记录地理位置
2、计算距离
3、查找"附近的人"
常见操作命令
命令名称 | 命令格式 | 描述 |
---|---|---|
geoadd | geoadd key 经度 纬度 成员名称 1 经度 1 纬度 1 成员名称 2 经度 2 纬度 2 … | 添加地理坐标 |
geohash | geohash key 成员名称 1 成员名称 2… | 返回标准的 geohash 串 |
geopos | geopos key 成员名称 1 成员名称 2… | 返回成员经纬度 |
geodist | geodist key 成员 1 成员 2 单位 | 计算成员间距离 |
georadiusbymember | georadiusbymember key 成员 值单位 count 数 asc[desc] | 根据成员查找附近 的成员 |
操作演示
127.0.0.1:6379> geoadd myloc 116.31 40.05 beijing 116.38 40.08 tianjin
(integer) 2
127.0.0.1:6379> geohash myloc beijing tianjin
1) "wx4eydyk5m0"
2) "wx4u0236ft0"
127.0.0.1:6379> geopos myloc beijing tianjin
1) 1) "116.31000012159347534"
2) "40.04999982043828055"
2) 1) "116.38000041246414185"
2) "40.08000078008021916"
127.0.0.1:6379> geodist myloc beijing tianjin km
"6.8294"
127.0.0.1:6379> georadiusbymember myloc beijing 20 km withcoord withdist count 3 asc
# 获得距离beijing 20km以内的按由近到远的顺序排出前三名的成员名称、距离及经纬度
#withcoord : 获得经纬度 withdist:获得距离 withhash:获得geohash码
1) 1) "beijing"
2) "0.0000"
3) 1) "116.31000012159347534"
2) "40.04999982043828055"
2) 1) "tianjin"
2) "6.8294"
3) 1) "116.38000041246414185"
2) "40.08000078008021916"
127.0.0.1:6379> georadiusbymember myloc beijing 20 km count 3 asc
1) "beijing"
2) "tianjin"
127.0.0.1:6379>
stream 是 Redis5.0 后新增的数据结构,用于可持久化的消息队列。
几乎满足了消息队列具备的全部内容,包括:
消息 ID 的序列化生成
消息遍历
消息的阻塞和非阻塞读取
消息的分组消费
未完成消息的处理
消息队列监控
每个 Stream 都有唯一的名称,它就是 Redis 的 key,首次使用 xadd 指令追加消息时自动创建。
应用场景
消息队列的使用
常见操作命令
命令名称 | 命令格式 | 描述 |
---|---|---|
xadd | xadd key id <*> field1 value1… | 将指定消息数据追加到指定队列(key)中,* 表示最新生成的 id(当前时间 + 序列号) |
xread | xread [COUNT count] [BLOCK milliseconds] STREAMS key [key …] ID [ID …] | 从消息队列中读取,COUNT:读取条数, BLOCK:阻塞读(默认不阻塞)key:队列 名称 id:消息 id |
xrange | xrange key start end [COUNT] | 读取队列中给定 ID 范围的消息 COUNT:返 回消息条数(消息 id 从小到大) |
xrevrange | xrevrange key start end [COUNT] | 读取队列中给定 ID 范围的消息 COUNT:返 回消息条数(消息 id 从大到小) |
xdel | xdel key id | 删除队列的消息 |
xgroup | xgroup create key groupname id | 创建一个新的消费组 |
xgroup | xgroup destory key groupname | 删除指定消费组 |
xgroup | xgroup delconsumer key groupname cname | 删除指定消费组中的某个消费者 |
xgroup | xgroup setid key id | 修改指定消息的最大 id |
xreadgroup | xreadgroup group groupname consumer COUNT streams key | 从队列中的消费组中创建消费者并消费数据 (consumer 不存在则创建) |
操作演示
127.0.0.1:6379> xadd topic:001 * name zhangfei age 23
"1627544298648-0"
127.0.0.1:6379> xadd topic:001 * name zhaoyun age 24 name diaochan age 16
"1627544346099-0"
127.0.0.1:6379> xrange topic:001 - +
1) 1) "1627544298648-0"
2) 1) "name"
2) "zhangfei"
3) "age"
4) "23"
2) 1) "1627544346099-0"
2) 1) "name"
2) "zhaoyun"
3) "age"
4) "24"
5) "name"
6) "diaochan"
7) "age"
8) "16"
127.0.0.1:6379> xread COUNT 1 streams topic:001 0
1) 1) "topic:001"
2) 1) 1) "1627544298648-0"
2) 1) "name"
2) "zhangfei"
3) "age"
4) "23"
##创建的group1
127.0.0.1:6379> xgroup create topic:001 group1 0
OK
# 创建cus1加入到group1 消费 没有被消费过的消息 消费第一条
127.0.0.1:6379> xreadgroup group group1 cus1 count 1 streams topic:001 >
1) 1) "topic:001"
2) 1) 1) "1627544298648-0"
2) 1) "name"
2) "zhangfei"
3) "age"
4) "23"
#继续消费 第二条
127.0.0.1:6379> xreadgroup group group1 cus1 count 1 streams topic:001 >
1) 1) "topic:001"
2) 1) 1) "1627544346099-0"
2) 1) "name"
2) "zhaoyun"
3) "age"
4) "24"
5) "name"
6) "diaochan"
7) "age"
8) "16"
#没有可消费
127.0.0.1:6379> xreadgroup group group1 cus1 count 1 streams topic:001 >
(nil)
127.0.0.1:6379>
subscribe:订阅 subscribe channel1 channel2 …
publish:发布消息 publish channel message
unsubscribe:退订 channel
psubscribe :模式匹配 psubscribe + 模式
punsubscribe 退订模式
操作演示
redis 客户端 1
27.0.0.1:6379> subscribe channel1 channel2
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "subscribe"
2) "channel2"
3) (integer) 2
1) "message"
2) "channel1"
3) "weather-cloudy"
1) "message"
2) "channel2"
3) "weather-sunny"
^C
➜ bin ./redis-cli
127.0.0.1:6379> unsubscribe channel1
1) "unsubscribe"
2) "channel1"
3) (integer) 0
127.0.0.1:6379> psubscribe ch*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "ch*"
3) (integer) 1
1) "pmessage"
2) "ch*"
3) "ch3"
4) "sky-blue"
^C
➜ bin ./redis-cli
127.0.0.1:6379> punsubscribe ch*
1) "punsubscribe"
2) "ch*"
3) (integer) 0
127.0.0.1:6379>
redis 客户端 2
127.0.0.1:6379> publish channel1 weather-cloudy
(integer) 1
127.0.0.1:6379> publish channel2 weather-sunny
(integer) 1
127.0.0.1:6379> publish ch3 sky-blue
(integer) 1
127.0.0.1:6379>
multi:用于标记事务块的开始 Redis 会将后续的命令逐个放入队列中,然后使用 exec 原子化地执行这个 命令队列
exec:执行命令队列
discard:清除命令队列
watch:监视 key
unwatch:清除监视 key
演示
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set s1 222
QUEUED
127.0.0.1:6379> hset set1 name zhangfei
QUEUED
127.0.0.1:6379> exec
1) OK
2) (integer) 1
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set s2 333
QUEUED
127.0.0.1:6379> hset set2 age 23
QUEUED
127.0.0.1:6379> discard OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
127.0.0.1:6379> watch s1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set s1 555
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get s1
222
127.0.0.1:6379> unwatch
OK
从 Redis2.6.0 版本开始,通过内置的 lua 编译/解释器,可以使用 EVAL 命令对 lua 脚本进行求值。
脚本的命令是原子的,RedisServer 在执行脚本命令中,不允许插入新的命令
脚本的命令可以复制,RedisServer 在获得脚本后不执行,生成标识返回,Client 根据标识就可以随时执 行
通过执行 redis 的 eval 命令,可以运行一段 lua 脚本。
EVAL script numkeys key [key ...] arg [arg ...]
命令说明:
script 参数:是一段 Lua 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该) 定义为一个 Lua 函数。
numkeys 参数:用于指定键名参数的个数。
key [key …]参数: 从 EVAL 的第三个参数开始算起,使用了 numkeys 个键(key),表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形 式访问( KEYS[1] , KEYS[2] ,以此类推)。必须大写
arg [arg …]参数:可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似(ARGV[1] 、 ARGV[2] ,诸如此类)。
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
redis.call():
返回值就是 redis 命令执行的返回值 如果出错,则返回错误信息,不继续执行
redis.pcall():
返回值就是 redis 命令执行的返回值 如果出错,则记录错误信息,继续执行
注意事项
在脚本中,使用 return 语句将返回值返回给客户端,如果没有 return,则返回 nil
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 n1 zhaoyun
127.0.0.1:6379> eval "return redis.call('set', KEYS[1] , ARGV[1])" 1 pokemon pikaqiu
OK
127.0.0.1:6379> eval "redis.call('set', KEYS[1] , ARGV[1])" 1 pokemon2 pikaqiu2
(nil)
127.0.0.1:6379> get pokemon
"pikaqiu"
127.0.0.1:6379> get pokemon2
"pikaqiu2"
EVAL 命令要求你在每次执行脚本的时候都发送一次脚本主体(script body)。
Redis 有一个内部的缓存机制,因此它不会每次都重新编译脚本,不过在很多场合,付出无谓的带宽来 传送脚本主体并不是最佳选择。
为了减少带宽的消耗, Redis 实现了 EVALSHA 命令,它的作用和 EVAL 一样,都用于对脚本求值,但 它接受的第一个参数不是脚本,而是脚本的 SHA1 校验和(sum)
SCRIPT 命令
SCRIPT FLUSH :清除所有脚本缓存
SCRIPT EXISTS :根据给定的脚本校验和,检查指定的脚本是否存在于脚本缓存
SCRIPT LOAD :将一个脚本装入脚本缓存,返回 SHA1 摘要,但并不立即运行它
SCRIPT KILL :杀死当前正在运行的脚本
127.0.0.1:6379> SCRIPT HELP
1) SCRIPT <subcommand> arg arg ... arg. Subcommands are:
2) DEBUG (yes|sync|no) -- Set the debug mode for subsequent scripts executed.
3) EXISTS <sha1> [<sha1> ...] -- Return information about the existence of the scripts in the script cache.
4) FLUSH -- Flush the Lua scripts cache. Very dangerous on replicas.
5) KILL -- Kill the currently executing Lua script.
6) LOAD <script> -- Load a script into the scripts cache, without executing it.
127.0.0.1:6379> script load "return redis.call('set', KEYS[1], ARGV[1] )"
"511348f1a6f431925095b437edc89b97e2575f0f"
127.0.0.1:6379> evalsha 511348f1a6f431925095b437edc89b97e2575f0f 1 xiaogang nibishi
OK
127.0.0.1:6379> get xiaogang
"nibishi"
使用 redis-cli 直接执行 lua 脚本。
test.lua
vim test.lua
#添加内容
return redis.call('set',KEYS[1],ARGV[1])
:wq
#,两边都要有空格
./redis-cli -h 127.0.0.1 -p 6379 --eval test.lua name:6 , caocao
list.lua
vim list.lua
#添加
local key=KEYS[1]
local list=redis.call("lrange",key,0,-1);
return list;
#执行
./redis-cli --eval list.lua list1
1) "3"
2) "2"
3) "1"
在 redis.conf 中可以配置和慢查询日志相关的选项:
#执行时间超过多少微秒的命令请求会被记录到日志上 0 :全记录 <0 不记录
slowlog-log-slower-than 10000
#slowlog-max-len 存储慢查询日志条数
slowlog-max-len 128
Redis 使用列表存储慢查询日志,采用队列方式(FIFO)
config set 的方式可以临时设置,
redis 重启后就无效
config set slowlog-log-slower-than 微秒
config set slowlog-max-len 条数
查看日志:slowlog get [n]
操作演示
127.0.0.1:6379> config set slowlog-log-slower-than 0
OK
127.0.0.1:6379> config set slowlog-max-len 2
OK
127.0.0.1:6379> set name:001 zhaoyun
OK
127.0.0.1:6379> set name:002 zhangfei
OK
127.0.0.1:6379> get name:002
"zhangfei"
127.0.0.1:6379> slowlog get #set和get都记录,第一条被移除了。
1) 1) (integer) 4 #日志的唯一标识符(uid)
2) (integer) 1627616880 #命令执行时的UNIX时间戳
3) (integer) 4 #命令执行的时长(微秒)
4) 1) "get" #执行命令及参数
2) "name:002"
5) "127.0.0.1:58834"
6) ""
2) 1) (integer) 3
2) (integer) 1627616874
3) (integer) 5
4) 1) "set"
2) "name:002"
3) "zhangfei"
5) "127.0.0.1:58834"
6) ""
127.0.0.1:6379>