Redis从入门到进阶(总结)
以下内容均以CentOS7为背景。
一、Redis安装及启动
mysql(读:2000/s;写:600/s)
redis(读:10w/s;写:8w/s)通过官方给出的数据单机并发可以达到10w/s;
redis是基于key-value型的非关系型数据库,目前redis无法取代关系型数据库的根本原因,redis是基于内存的,断电即丢失,虽然有rdb和aof两种持久化机制但是,因为持久化是异步的,所以还是会存在数据丢失的情况;
redis官方版本,以6.2.7为例,版本号第一位是大版本,第二位如果是奇数则该版本为非稳定版本,偶数则相反;
首先在CentOS7中使用命令安装redis6.2.7:
wget https://download.redis.io/releases/redis-6.2.7.tar.gz
当使用以上命令从官网获取到完整redis6.2.7安装包后,再使用解压命令解压至opt/redis-6.2.7下
tar -zxvf redis-6.2.7.tar.gz
随后进入解压后的redis6.2.7文件夹中,使用命令进行编译
make
至此redis安装完毕,虽然redis是用c写的,但是只依赖linux系统基本的类库,一般情况下很少出问题。
如果执行make命令报错:cc未找到命令,是因为虚拟机系统中缺少gcc库,执行以下命令安装gcc库即可;
yum -y install gcc automake autoconf libtool make
如果执行make命令报错:致命错误:jemalloc/jemalloc.h:没有那个文件或目录,则需要在make指定分配器为libc,执行以下命令即可;
make MALLOC=libc
bin目录下可执行文件:
redis-server: 启动redis;
redis-cli: 命令行工具;
redis-benchmark: 基准测试工具;
redis-check-aof: AOF持久化文件检测和修复工具;
redis-check-rdb: RDB持久化文件检测和修复工具;
redis-sentinel: 启动哨兵;
启动方式:
一:默认启动
进入bin目录执行以下命令:
./redis-server
二:带参数启动(以指定端口为例)
进入bin目录执行以下命令:
./redis-server --port 6380
三:配置文件启动
进入bin目录执行以下命令:
./redis-server ../redis.conf
如果要设置登陆密码则需要修改配置文件中的requirepass参数;
redis-cli命令行工具支持两种方式:
一:不带参数默认是连本地的redis服务;
./redis-cli
二:带参数单条命令;
./redis-cli -p 6379 set key value
停止redis:
一:杀死进程,强制停止(直接杀死进程会使redis还没有来得及做持久化就被强制停止,导致数据丢失);
kill -9 pid
二:在命令行工具内;
shutdown(有NOSAVE|SAVE两种,默认是SAVE)
二、Redis全局命令
查看所有键
keys *(查看所有,不推荐使用该命令,如果数据量过大该命令会导致线程阻塞,时间复杂度为O(n))
keys u*(带通配符)
dbsize(查看redis内key总数,该命令基于计数器,所以效率很快,时间复杂度为O(1))
exists(查看某一键是否存在,存在返回1,不存在则返回0)
del(删除指定键,后面可跟多个key,返回删除键的数量)
expire(对指定键设置过期时间,以秒为单位,成功返回1,失败返回0)
pexpire((对指定键设置过期时间,以毫秒为单位,成功返回1,失败返回0))
ttl(查看指定键的过期时间,如果键存在且设置的有过期时间,则返回剩余的过期时间,如果键存在但是没有设置过期时间,则返回-1,如果键不存在则返回-2)
存在过期时间但是还没有过期,返回剩余过期时间:
键存在,但是永不过期,返回-1:
键不存在,返回-2:
expireat(对指定键设置指定时间过期,时间戳,成功返回1,失败返回0)
(对于key设置过期时间,需要注意,如果对一个可以设置完过期时间之后再次进行set 这个key时,会将之前的key覆盖掉,同时会将对之前key设置的过期时间抹去)
type(查看指定key的数据类型,如果存在返回该key的数据类型,如果不存在则返回none)
rename(对指定key重命名,成功返回OK,失败返回no such key)
(对于某一个key重命名不会导致过期时间失效,如果在重命名的过程中发现key已经存在,则会将value进行覆盖)
renamenx(如果新key已经存在则不修改,成功返回1,失败返回0)
randomkey(从已有的key中随机返回一个key)
三、数据类型
String:
Redis的String类型并没有直接使用C的String类型,而是自己去实现的。字符串最大不能超过512M。一般用于缓存、共享session、计数器等,时间复杂度基本都是O(1)。
命令:
set key value (n次网络+n次命令)
get key (获取指定key的value值)
setnx key value(添加的键必须不存在才可以设置)
set key value nx(上一条命令的变种,效果一样,不存在才设置)
set key value xx (存在才设置)
mset [key value](批量添加 1次网络+n次命令)
mget [key value](批量获取 1次网络+n次命令)
incr key (键自增)
decr key (键自减)
incrby key increment (指定键按照指定步长自增)
decrby key decrement (指定键按照指定步长自减)
incrbyfloat key increment(指定键按照指定步长自增)
append key value (指定键后面追加内容)
strlen key (返回字符串value的长度)
getset key value (返回set之前的value值)
setrange key offsetvalue (在指定key的value指定位置上添加值)
getrange key start end(返回指定key指定范围内的数据)
Hash:
命令:
hset key field value(哈希添加)
hget key field (哈希获取)
hsetnx key field value (不存在添加)
hdel key field (删除指定key的指定字段)
hlen key (获取指定key的字段数)
hmset key field value (批量添加)
hmget key field (批量获取)
hexists key field (查看指定key下指定字段是否存在)
hkeys key (获取指定key下所有field)
hvals key (获取指定key下所有value)
hgetall key (获取指定key下所有field-value)
hincrby key field increment (指定key下指定field按照指定步长自增)
List:
有序的,可以有重复的元素,list最大的存储元素个数:2的32次方-1(42 9496 7295),文章列表,分页等,消息队列;
命令:
rpush key element(从右边插入元素)
lpush key element(从左边插入元素)
rpop key (从右边弹出元素)
lpop key (从左边弹出元素)
lrang key start end (从左边截取指定长度的数据并返回)
lrem key count element (删除指定key中指定数量的指定元素)
ltrim key start end (保留从指定起止裁剪指定key的list)
lset key index element (将指定key的指定位置设置为指定元素)
lindex key index (获取指定key指定位置上的元素)
llen key (获取指定key的元素长度)
blpop key timeout (阻塞式左边弹出,如果有元素直接返回,如果没有元素,则阻塞至超时返回,如果将timeout设置为0则一直阻塞)
brpop key timeout (阻塞式右边弹出,如果有元素直接返回,如果没有元素,则阻塞至超时返回,如果将timeout设置为0则一直阻塞)
Set:
无序的,不允许有重复的元素,最大的存储元素个数:2的32次方-1(42 9496 7295),标签、共同爱好等;
命令:
sadd key member(添加元素,并且过滤掉重复元素)
smembers key (查看指定key的元素集合)
srem key member (删除指定key下的指定元素)
scard key (统计指定key下有多少个元素)
sismember key member (判断指定key下是否包含指定元素,1存在,0不存在)
srandmember key count (随机返回指定key下的某个元素,不设置count默认为1个)
spop key (从指定key中随机弹出一个元素)
sinter keys(查看多个指定key中的交集)
sunion keys(查看多个指定key中的并集)
sdiff keys(查看多个指定key中的差集)
sinterstore destination keys (查看多个指定key中的交集并将结果保存为一个集合)
Zset:
有序的,不允许有重复的元素,可以用作排行榜;
命令:
zadd key score member(添加指定key中的score和member)
zcard key(查看指定key中包含的元素)
zscore key member (查看指定key中指定member的score)
zrank key member(查看指定key中指定member的排名)
zrevrank key member(在上一条命令的基础上进行排名的反转)
zrem key member(删除指定key中指定member)
zincrby key increment member (将指定key中的指定member增加指定的数)
zrange key min max(按照指定范围内查看指定key中的结果集,默认升序)
zrevrange key min max (基于上条命令的倒序)
zrangebyscore key min max (按照score指定范围内指定key中的member)
Bitmaps:
按位存储,网站统计访问量、布隆过滤器(关于布隆过滤器误判的问题,本质是hash冲突导致的,通过hash计算在数组上的不一定在,但是不在数组上的一定不存在,解决方案是增大数组,增加hash函数)缓存穿透;
命令:
setbit key offset value(对指定key的某个偏移量上设置value)
getbit key offset (获取指定key下指定偏移量是否存在,1存在,0不存在)
bitcount key start end (统计指定key中的数量)
GEO:
地理定位信息,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能;
命令:
geoadd key lon lat member(向指定key中添加元素以及经纬度)
geopos key member (获取指定key中member的经纬度)
HyperLogLog:
大型网站每个网页每天的UV(独立访客)数据,HyperLogLog提供不精确的去重计数方案,标准误差是0.81%,HyperLogLog基于概率论中伯努利试验并结合了极大似然估算方法,并做了分桶优化;
命令:
pfadd key element (指定key添加element)
pfcount key (统计指定key下的所有元素)
四、Redis高级特性与应用
慢查询
redis的慢查询记录在slowlog的链表中(内存队列),链表的长度在redis.conf中由参数slowlog-max-len控制,通过slowlog-log-slower-than配置慢查询阈值,以微秒为单位,可以通过动态的设置,如果设置为负值则都不记录,redis执行命令分为四个阶段,第一阶段为发送命令,将命令由客户端发送至服务端,第二阶段排队,接收到客户端发送的命令后排队,第三阶段执行命令,慢查询指的就是在第三阶段的耗时,第四阶段就是返回结果。
在redis-cli工具中可以通过以下命令动态设置慢查询阈值,并回显到配置文件中:
config set slowlog-log-slower-than 20000(设置慢查询阈值)
config rewrite (回显)
可以通过以下命令查看慢查询记录:
slowlog subcommand argument
可以通过以下命令清空内存中的慢查询记录链表:
slowlog reset
Pipeline
redis执行命令大多都很快,但是由于网络io可能会导致RTT(Round-Trip Time 往返时间在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(不包含数据传输时间)总共经历的时间,RTT由三个部分决定:链路的传播时间、末端系统的处理时间、路由器的缓存中的排队和处理时间)变长,所以可以使用Pipeline技术批量操作,减少网络io带来的延迟,提高吞吐量。
事务
redis中的事务只能判断最基本的语法错误,运行时的错误无法回滚,无法保证事务的原子性,所以一般不采用redis的事务机制。
multi(开启事务)
exec(执行)
watch机制属于一种cas操作,将指定的元素监控起来,如果该元素被其他客户端修改,则该事务执行失败。
watch key
Lua
lua脚本语言是c开发的,类似于存储过程,在lua脚本中可以把多个命令放在同一个脚本中运行,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入,可以减少网络开销,客户端发送的脚本会存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑,应用场景:分布式限流。
redis2.6及以上内嵌支持了lua脚本。
eval script numkeys key arg (script脚本 numkeys key的数量 key key列表 arg 参数列表)
script load (缓存指定脚本)
evalsha (从缓存中引用指定脚本)
发布 订阅
发送即忘
publish channel message
此时返回的0是当前订阅该消息的订阅者数量,因为当前消息组没有人订阅,该消息被丢弃,再起一个客户端去订阅这个组:
当订阅完成再去发送消息:
此时订阅该消息的客户端将会接收到消息:
查看当前所有消息组:
也支持通配符查找:
查看指定消息组的订阅者数量:
更多的命令可以通过help查看:
Stream
Stream是一种新的数据类型,于Redis 5.0版本中引入。它是一个有序、持久化、可重复读的消息流,可以用于实现消息队列、日志系统等应用场景。
向指定队列添加消息,*代表通配符,表示id由redis生成;
查看指定队列中的消息;
查看指定队列中消息的数量;
删除指定生产者中的消息;
从指定生产者中读取指定数量及范围的消息;
从指定生产者中阻塞式读取指定数量及范围的消息;
对指定生产者创建消费者群组;
查看指定生产者的信息;
查看订阅了指定生产者的消息群组;
指定消费群组的消费者来消费指定生产者的消息;
确认接受消息;
五、Redis数据结构
redis采用全局哈希表的方式,哈希表由数组加链表构成,每一个entry包含key指针、value指针、以及next指针, 如果数组长度过短会导致链表过长,当链表数据过长时会rehash对数组进行扩容,数组扩容之后之前的链表上的数据需要迁移到数组重新计算之后的索引上,如果数据量过大会导致IO阻塞,redis则采用两张全局hash表以及渐进式rehash的方式解决:
六、Redis的持久化
Redis支持RDB和AOF两种持久化方式;
RDB:
有两个命令可以手动去生成快照:
save(会占用主线程导致阻塞)
执行完之后会在执行目录中多出一个dump.rdb的文件
bgsave(非阻塞式,redis默认的保存快照的方式,会创建一个子线程用于保存快照)
在redis的配置文件中可以去配置触发自动保存的策略,在redis.conf中如下:
save 3600 1 (3600秒之内保存一次触发)
save 300 100 (300秒之内保存100次触发)
save 60 10000 (60秒之内保存10000次触发)
如上触发策略可以有多个,只要满足一个就会触发bgsave操作。
bgsave操作避免阻塞的原理:
当触发bgsave操作时,Redis会fork出一个子进程,负责将Redis当前内存中的数据写入RDB文件中。子进程首先将所有键值对写入临时文件中。当所有键值对都写入完毕后,子进程用新的RDB文件替换旧的RDB文件。在此期间,Redis主进程仍然可以处理客户端请求,并向子进程发送新的写命令以更新临时文件。与此同时,Redis还会记录RDB文件生成的时间戳,以及最后一次成功执行bgsave命令的时间戳。
Redis的自动持久化机制:
1、在使用shutdown结束Redis时,Redis会自动使用RED的方式进行持久化;
2、从节点执行全量赋值操作,主节点会自动执行bgsave操作生成一个RDB文件发送给从节点。
在redis.conf文件中可以通过dbfilename属性设置生成的RDB文件的名字,dir属性设置文件保存路径,如果不想触发任何保存操作则将save保存策略全部注释掉,并添加save “ ”,则Redis不会再触发自动保存操作,或者可以通过在redis-cli工具中执行config set value命令动态的进行设置。
RDB文件是一种二进制的压缩文件,在redis.conf中rdbcompression属性默认为yes,指开启动态压缩算法,采用了一种LZF的压缩算法。
可通过redis-check-rdb或redis-check-aof对rdb或aof文件进行校验,返回ok则成功:
Redis的AOF持久化
Redis中的AOF持久化机制遵循RESP的文本协议;
appendonly开启AOF持久化的参数 默认为no 不开启
appendfilename指定aof文件名
以命令的形式触发aof重写
appendfsync always 每一次写命令同步一次,会导致redis的效率非常低
appendfsync everysec 每秒钟同步一次写命令
appendfsync no 由操作系统控制,一般默认周期为30秒,可能会导致数据丢失
aof重写时文件的最小体积;
Redis重启加载流程:
Redis采用混合持久化模式:
通过配置文件中aof-use-rdb-preamble参数控制,默认为yes开启;
混合持久化流程:
通过info stats命令可以查看fork出子进程消耗的时间,单位微秒;
七、Redis的分布式锁
基于Redis中setnx命令的互斥
以上可能会造成死锁的问题,可以通过加过期时间解决
八、Redis的复制
由于时间原因,后面还有很长的篇幅,随缘更新。。。
原文地址:https://blog.csdn.net/weixin_53830969/article/details/134568826
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!