Redis是什么?
简介
Redis全称Remote Dictionary Server(远程字典服务),它由C语言编写,是一个高性能的键值对数据库,由于采用了内存存储数据,读写速度非常快。
每个redis服务有0-15一共16个数据库,每个数据库之间的数据相互独立。
主要应用场景
热点数据加速查询,秒杀,即时信息查询,分布式数据共享,消息队列,分布式锁
Redis常用数据类型
数据类型 | |
---|---|
string | 字符串 |
list | 列表 |
hash | 散列 |
set | 集合 |
sorted_set | 有序集合 |
我该如何使用它?
下载Windows版Redis并启动
https://github.com/microsoftarchive/redis/releases
安装后会自动配置环境变量并在系统的服务里自动添加redis并设为自动模式
在安装文件夹里打开 redis-server.exe也可以启动服务
启动redis后在CMD使用登录命令 redis-cli 显示"127.0.0.1:6379>"就登录成功了
Redis常用命令查询
数据库命令 | 作用 |
---|---|
select index | 选择数据库 |
quit | 退出redis-cli |
ping | pang!!! |
echo “hello world” | HelloWorld |
move key db | 数据移动到别的库 |
dbsize | 查看当前数据库数据总数 |
flushdb | ? |
flushall | ??? |
key命令 | 作用 |
---|---|
exists key | 是否存在某个key |
del key | 删除一个key |
type key | 查看key的类型 |
expire key seconds | 为key设置秒级的有效期 |
pexpire key milliseconds | 为key设置毫秒级的有效期 |
expireat key timestamp | 为key设置秒级的到期时间戳 |
pexpireat key milliseconds-timestamp | 为key设置毫秒级的到期时间戳 |
ttl key | 查询有效期秒(永久有效为-1) |
pttl key | 查询有效期毫秒(永久有效为-1) |
persist key | key改为永远有效 |
keys 通配符 | 查找符合条件的键值对(*任意数量任意字符 ?任意字符 []指定字符 [a]匹配a [ab]匹配a或b) |
sort key | 集合自身元素排序并返回排序结果 |
help @generic | 其他key通用操作 |
string命令 | 作用 |
---|---|
set key value | 存储 |
get key | 查询 |
del key | 删除 |
mset key1 value1 key2 value2 … | 存储多个 |
get key1 key2 … | 查询多个 |
strlen key | 计算字符串长度 |
append key value | 追加字符串内容 |
incr key | value自增1 |
decr key | value自减1 |
incrby key n | value自增n |
decrby key n | value自减n |
incrbyfloat key f | integer自增小数 |
setex key s value | 设置有生命周期的数据(秒) |
psetex key ms value | 设置有生命周期的数据数据(毫秒) |
hash命令 | 作用 |
---|---|
hset key field value | 存储哈希域值 |
hget key field | 获取哈希域值 |
hgetall key | 获取全部哈希域值 |
hdel key field | 删除哈希域值 |
hmset key f1 v1 f2 v2 … | 存多个 |
hmget key f1 f2 … | 查多个 |
hlen | hash表的字段数量 |
hexists key field | 是否存在某个字段 |
hkeys key | 显示一个key的全部哈希字段 |
hvals key | 显示一个key的全部哈希域值 |
hincrby key field | key的一个哈希域值自增整数 |
hincrbyfloat key field | key的一个哈希域值自增小数 |
list命令 | 作用 |
---|---|
lpush key val1 val2 … | list头增加节点 |
rpush key val1 val2 … | list尾增加节点 |
llen key | list的长度 |
lindex key index | 取list指定下标的值 (从零开始) |
lrange key X Y | 取list从X到Y的数据 (包括X和Y) |
lpop | 弹出头数据 |
rpop | 弹出尾数据 |
lrem key count val | 从列表头开始删除指定数量的val |
blpop key1 key2 … timeout | 在列表头查询val 可设定超时时间 |
brpop key1 key2 … timeout | 在列表尾查询val 可设定超时时间 |
set命令 | 作用 |
---|---|
sadd key val1 val2 … | 新增数据 |
srem key val1 val2 … | 删除数据 |
smembers key | 查看所有数据 |
scard key | 数据总条数 |
sismember key member | 是否有某个数据成员 |
srandmumber key count | 随机展示count条数据(随机推荐) |
spop key | 随机弹出一条数据 |
sinter key1 key2 … | 多个set求并 |
sunion key1 key2 … | 多个set求交 |
sdiff key1 key2 … | 多个set求差 |
sinterstore target key1 key2 … | 多个set求并 存储到target |
sunionstore target key1 key2 … | 多个set求交 存储到target |
sdiffstore target key1 key2 … | 多个set求差 存储到target |
smove source target member | 从source到taarget移动一个元素过去 |
sorted_list命令 | 作用 |
---|---|
zadd key member1 score1 member2 score 2 … | 添加或更新权值和数据 |
zrem key member1 member2 … | 删除一条 |
zrange key x y [withscores] | 取数据(权值从小到大) |
zrevrange key x y [withscores] | 取数据(权值从大到小) |
zrangebyscore key minScore maxScore [withscores][LIMIT offset count] | 在指定范围的score中取数据,支持增减limit属性进行分页,offset为偏移量,count为单页数据条数 |
zremRangebyRank key min max | 根据rank范围删除 |
zremRangebyScore key min max | 根据score范围删除 |
zcard key | 数据总条数 |
zcount key minScore maxScore | 根据score范围计算数据总条数 |
zinterstore target numkeys key1 key2 … | 多个sorted_set求交,numkeys是key的数量,结果成员的score为原成员每个score之和 |
zunionstore target numkeys key1 key2 … aggregate max/min | 多个sorted_set求并,numkeys是key的数量,结果成员的score为原成员每个score中最大或最小的值 |
zrank key member | 获取一个member的排名(从0开始) |
zincrby key num member | 一个member的score自增num |
Redis常用配置查询
RDB配置 | 作用 |
---|---|
dbfilename dump-6380.rdb | rdb文件名 |
stop-writes-on-bgsave-error yes | 后台存储时出现错误时停止保存 |
save second changes | 例如save 900 1 九百秒内有一次数据改变就bgsave一次(可以配置多项) |
rdbcompression yes | 是否压缩rdb文件 |
rdbchecksum yes | rdb文件数据校验(耗CPU) |
AOF配置 | 作用 |
---|---|
appendonly yes/no | 开启AOF持久化 |
appendfilename appendonly-6379.aof | AOF文件名 |
appendfsync always/everysec/no | 写入AOF文件的三种策略:每次,每秒(安全&效率),由系统控制 |
auto-aof-rewrite-percentage percentage | 目前aof文件超过上次aof文件的%多少后进行重写 |
auto-aof-rewrite-min-size size | 允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写 |
aof-rewrite-incremental-fsync yes | 重写过程中每32M进行一次同步 |
删除配置 | 作用 |
---|---|
maxmemory | 最大可用内存 |
maxmemory-samples | 待删除数据数量 |
maxmemory-policy | 采用哪种逐出策略(volatile-lru(常用)/volatile-lfu/volatile-ttl/volatile-random/allkeys-lru/allkeys-lfu/allkeys-random/no-enviction(默认策略:不驱逐))volatile指有失效期的数据,allkeys指全部数据 |
服务器基础配置 | 作用 |
---|---|
daemonize yes/no | 以守护进程方式运行 |
bind 127.0.0.1 | 绑定主机地址 |
port 6379 | 设置端口号 |
databases | 设置数据库数量 |
loglevel debug/verbose/notice/warning | 日志级别 |
logfile xxxx-6379.log | 日志文件名 |
maxclients 0 | 同时最大客户端连接数默认无限制,达到上限会关闭新的连接 |
timeout 300 | 客户端闲置等待时间 |
include /path/server-端口号.conf | 导入配置文件 |
Redis数据类型详细解释
string类型
redis中最简单的key-value存储格式,可以存储字符串和纯数字,例如我们设计了下面的格式来缓存Mysql数据
key | value |
---|---|
表名:主键名:主键值:字段名 | 字段值 |
例如在Mysql中查询sam123用户的年龄为
select age from user where username = “sam123”
则在Redis中查询sam123用户的年龄为
get user:username:sam123:age
Redis存储此数据则用
set user:username:sam123:age 21
数据查询大致流程是
if (redis has data)
query redis;
else
query mysql and save data into redis;
hash类型
一个key对应一个hash表,每个hashmap表内有多个field,每个field对应一个value,hash禁止嵌套使用,hash最多可以存储2^32-1个键值对。
list类型
双向链表,前后插,前后弹出,总长度,随意部分截取,下标取值。
list里保存的数据都是string,最多可以存储2^32-1个值。
一般用于栈和队列。
list可以作为分页的第一页实现快速响应。
点赞,关注列表等。
set类型
类似hashset,以没有value的hashmap作为存储数据的结构,快速高效,存储多个无序不重复数据,重复添加会失败。
使用场景:
统计UV(独立访客):每个独立访客每天访问第一次被set-add,第二次set-add将会失败,因为set对每个数据只允许一条记录。
统计IP:每个IP第一次访问会被记录。
黑名单/白名单
sorted_set类型
对比set增加了负责排序权重的字段score ,从而实现有序的set结构。注意,score为整数时占64位,为双精度double时数据可能会丢失精度。
使用场景:
排名统计,投票,人气榜单,任务权重优先处理。
Redis数据持久化的方法
- RDB
数据快照,将数据当前状态保存下来。 - AOF
日志,保存操作过程,改记录数据为数据产生的过程。
RDB快照
命令 | 作用 |
---|---|
save | 创建快照(阻塞) |
bgsave | 后台创建快照(非阻塞) |
特殊的RDB情况:
- 主从复制
- debug reload 服务器运行过程中重启
- shutdown save 关闭服务器保存
RDB的优缺点:
存储效率高,适合数据备份,恢复快,灾难恢复。
无法实时备份,开进程牺牲性能,RDB文件格式每个版本不统一。
AOF日志
命令 | 作用 |
---|---|
bgrewriteaof | 手动重写 开子进程重写.aof文件(不常用) |
AOF工作流程:
- 设置appendfsync(文件追加写入同步频率)为每秒一次,redis建立aof缓冲区记录新的日志,redis建立aof重写缓冲区记录重写的内容,每秒将aof缓冲区同步到硬盘的aof文件上,此文件还未被重写。
- 当符合重写的条件时,自动执行bgrewriteaof命令,开启重写进程,根据aof重写缓冲区内容生成重写后的aof文件并替代原来的aof文件。
RDB与AOF对比
对比项 | RDB | AOF |
---|---|---|
占用空间 | 空间小 | 空间大 |
存储速度 | 存储慢 | 存储快 |
恢复速度 | 恢复快 | 恢复慢 |
安全性 | 不安全 | 安全 |
资源消耗 | 消耗高 | 消耗低 |
总结:数据重要用AOF,追求回恢复速度用RDB,灾难恢复用RDB,双保险都用。
Redis的事务
命令 | 作用 |
---|---|
multi | 开启事务 |
exec | 执行事务 |
discard | 开启事务后出现问题,取消事务 |
watch key1 key2 … | 事务开始前,给若干个key加监控锁,若执行事务时key改变了,则事务不执行返回nil |
unwatch | 取消所有watch锁 |
setnx lock-key val | 加公共锁 |
del lock-key | 解公共锁 |
事务开始后,出现语法错误,事务销毁。 | |
事务开始后,出现运行错误,事务正常运行,错误的命令会有报错,但redis不提供回滚功能,由开发人员负责恢复。 |
分布式锁
set的参数 | 作用 |
---|---|
ex | 设置key多少秒之后过期 |
px | 设置key多少毫秒之后过期 |
nx | 只有key不存在时,set操作才会生效 |
xx | 只有key存在时,set操作才会生效 |
分布式锁(全局锁)利用了setnx来限制其他人无法创建一个已有的锁,当使用完毕后用del删除此锁,注意:不管锁获得与否,都可以对数据修改,此锁并不是真正意义上的锁住数据,而是为暂时为不可操作的数据进行标记而已。
锁的命名规则应统一,不然就无法起到标记作用了…
set lock-name 1 EX 60 NX
为name这个key设置锁,锁的值为1(锁的值随便设置因为无所谓比如标记获得锁的员工号),EX 60是生命周期60s,NX限制这个key必须为nil时才能set成功。
Redis的删除策略
- 准时删除:给key设置有效期,到期立刻删除,快速释放内存空间,占CPU,省内存,时间换空间。
- 惰性删除:给key设置有效期,到期不删除,访问时发现过期才删除。get指令时调用expireIfNeeded()检测key是否失效。占内存,省CPU,空间换时间。
- 定期删除:每秒钟执行若干次检查,每次检查遍历所有库,一个库随机检测W个有期限的key的有效期,进行删除操作。如果一次性删除了W/4个以上的key,则再进行一轮删除。每次检查执行250/server.zh毫秒。W(ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP)和server.zh通过配置文件进行配置。
周期性随机抽查重点抽查,CPU占用有峰值,内存压力不大。 - 逐出算法:当内存满了,需要存新数据,临时删除一些数据的策略。
LRU算法:最近最少使用逐出
LFU算法:最不经常使用逐出
FIFO算法:先进入先逐出
ttl算法:最先到期逐出
random算法:随机逐出
redis高级数据类型
bitmap用比特位来存储0或1的数据
Bitmaps命令 | 作用 |
---|---|
setbit key offset value | 设置某个偏移量的bit值 |
getbit key offset | 获取某个偏移量的bit值 |
bitcount key start end | 统计key中1的数量 |
bitop op destKey key1 key2 … | op为逻辑操作,and交/or并/not非/xor异或,结果存入destKey中 |
基数:去重后的元素个数
Hyperloglog采用基数估算算法有0.81%的误差,上限占用12k空间,合并后直接达到12k
Hyperloglog命令 | 作用 |
---|---|
pfadd key val1 val2 … | Hyperloglog添加数据 |
pfcount key1 key2 … | Hyperloglog统计数据 |
pfmerge destkey key1 key2 … | Hyperloglog合并数据 |
GEO地图坐标
GEO命令 | 作用 |
---|---|
geoadd | 添加坐标 |
geopos | 获取坐标 |
geodist | 计算坐标距离 |