Redis
2021-06-22 14:49:40 2 举报
AI智能生成
Redis
作者其他创作
大纲/内容
Redis
简介
Re di s(Remote Dictionary Server)远程字典服务
Redis是基于C语言编写的的kv键值对数据库
性能方面
每秒可读11万次
每秒可写8万1千次
为什么Redis性能高?
Redis其实是单线程的,它基于内存操作,它的性能瓶颈其实是内存大小,频率,以及网络带宽
而且并不是多线程的性能就一定高,cpu上下文切换也需要消耗性能,这种切换一旦过多,就会造成资源浪费
Redis的默认端口是6379(这个其实是因为作者把某个女星的姓名用九宫格打出来是6379)
安装Redis
windows下安装(不推荐)
在github上搜索Redis,下载zip压缩包,解压即可
找到解压后的文件
大概就是这样
双击Redis.server.exe打开Redis
这个终端窗口不要关闭,不然服务就会被终止
双击Redis-cl.exei测试
测试是否连接成功
测试存取值
Linux下安装(官方推荐)
下载安装包(Redis.io)
发送到服务器的opt(软件一般都安装在这里)目录下
解压压缩包
编译需要环境支持,如果没有c++环境的先配置环境
yum install gcc-c++
进入Redis文件夹进行软件编译
输入make
输入make install
然后我们会在/usr/local/bin下发现我们已经安装好的Redis
接下来我们修改Redis的配置文件,改成后台运行
大概在11%的位置
然后我们在/usr/local/bin下建立一个专门存放Redis配置文件的文件夹,因为Redis之后组集群会有很多配置文件
就像这样
测试Redis
开启并连接
关闭并退出
外部访问记得打开防火墙
初始Redis
Redis的数据库
Redis一共有16个数据库
如图
Redis的16个数据库是相互独立的,可以使用select index进行切换
清空Redis数据
flushdb
清除当前数据库的数据
flushall
清空所有数据库的记录
Redis可以设置过期时间
五大数据类型
String(就是类似java中的字符串操作)
基本字符串
设置值
set [key] [value]
取值
get [key]
追加值
append [key] [value]
查看长度
strlen [key]
截取字符串范围(闭区间)
getrange [key] [start] [end]
getrange [key] 0 -1就是完整字符串
替换(相当于replace)
setrange [key] [start] [new]
带过期时间的设置
setex [key] [seconds] [value]
setex(set with expire)
不存在设置
setnx [key] [value]
如果不存在这个key,就存储
如果已经有了这个key,该操作无效
可以批量添加,并且是原子操作
批量添加记录
mset k1 v1 k2 v2 ...
浏览量类型的字符串
自增
incr view
自减
decr view
固定长度自增
incrby view [num]
固定长度自减
decrby view [num]
存储对象
set user:id:name xiaoming
set user:id:age 20
List
本质
是个双向链表
允许存在重复元素
存元素
左存(头插)
lpush [list] [value]
右存(尾插)
rpush [list] [value]
移除元素
左取
lpop [list]
右取
rpop [list]
移除指定的元素
lrem [list] [num] [value]移除 某list num数量个 值为value的节点元素
根据index操作
lindex [list] [index]
获取list长度
llen [list]
range操作
lrange [list] [start] [end]
trim操作(把截取作为新的list替代旧的)
ltrim [list] [start] [end]
判断list是否存在
exists [list]
替换节点值(把index下标的值用value替换,不存在就报错)
lset [list] [index] [value]
插值(在value0 前 | 后 插入value1的值)
linsert [list] [before | after] [value0] [value1]
Set(无序不重复集合)
添加记录
sadd [set] [member]
查看指定set的所有值
smembers [set]
查看指定set的元素个数
scard [set]
移除指定set的指定值
srem [set] [member]
随机获取一个元素
srandmember [set]
随机获取num个元素
srandmember [set] [num]
随机移除一个元素
spop [set]
从oldset移动指定的元素到newset
smove [oldset] [newset] [member]
找set1和set2中的差集
sdiff [set1] [set2]
找set1和set2中的交集(共同关注可以这样实现)
sinter [set1] [set2]
找set1和set2中的并集
sunion [set1] [set2]
Hash
存值
hset [map] [key] [value]
批量存值
hmset [map] [k1] [v1] [k2] [v2] ...
hget [map] [key]
批量取值
hmget [map] [k1] [k2] ...
获得所有的k-v
hgetall [map]
获得k-v键值对数量
hlen [map]
判断key是否存在
exists [map] [key]
只获得所有的key
hkeys [map]
只获得所有的value
hvals [map]
设置不存在的k-v键值对(如果没有就设置成功,如果已经存在就设置失败)
hsexnx [map] [key] [value]
Zset(带score的有序集合)
添加
zadd [set] [score][member]
批量添加
zadd [set] [score1] [member1] [score2] [member2] ...
移除
zrem [set] [member]
获得指定set的数量
zcard [set]
按照score升序获得min到max区间的所有member
zrangebyscore [set] [min] [max]
按照score降序获得min到max区间的所有member
zrevrangebyscore [set] [min] [max]
带score查询
zrangebyscore [set] [min] [max] withscores
三种特殊数据类型
Geospatial(地理位置)
底层实现是zset,我们可以使用相关命令
有效经度是-180到180
有效纬度是-85到85
添加地理位置
geoadd [key] [经度] [纬度] [名称] [经度] [纬度] [名称]..
geoadd city 116.39 39.91 beijing 121.48 31.40 shanghai 113.27 23.15 guangzhou 113.88 22.55 shenzhen
查看指定key的经纬度
geopos [key] [名称] [名称] ...
geopos city beijing
查看指定key已有地点
通过zset命令实现
zrange [key] 0 -1
移除地理位置
zrem [key] [名称]
zrem city chengdu guangzhou
两地之间的距离
geodist [key] [地点1] [地点2] [ m | km | ft | mi ]
geodist city beijing shanghai km
以一点为中心(给出经纬度),找出指定距离为半径的圆内地点(附近的人)
georadius [key] [经度] [纬度] [半径] [单位] ...
georadius city 108 28 2000 km withcoord withdist count 2
以一点为中心(使用zset中的member),找出指定距离为半径的圆内地点(附近的人)
georadiusbymember city beijing 3000 km withcoord withdist count 2
根据经纬度获取一个哈希值
geohash [key] [地点] [地点] [地点] ...
距离越近,获得的哈希值越接近
Hyperloglog(基数计算)
内存占用小,适用于uv浏览量统计,有极小的误差
通过hash函数映射,并不存储元素本身,所以无法查看指定key的已存入元素
pfadd [key] [member] [member] ...
统计数量
pfcount [key]
合并多个集合形成一个新的集合
pfmerge [newkey] [key1] [key2] ...
Bitmap(位图,可以记录唯二状态的记录,按位操作)
添加操作
setbit [map] [ 0 | 1 ]
查询操作
getbit [map] [index]
统计操作
bitcount [map]
事务
⭐Redis的事务不保证原子性
每次使用事务都需要手动开启,声明周期到执行或者放弃结束
开启事务
multi
命令入队
输入命令
放弃事务
discard
执行事务
exec
异常
命令有错(相当于编译异常)
事务整体都不会有效
事务队列存在运行错误(运行时异常)
有错误的命令不生效但是不影响事务中别的命令
可以使用watch做乐观锁操作(失败了就unwatch,然后重复操作,达到自旋效果)
SpringBoot整合
Jedis
新建项目,引入依赖
pre style=\
配置一下远程Redis
开启后台运行
开启保护模式
设置密码
重启Redis服务
打开redis-cli连接本地服务,需要输入auth 密码才能继续后续操作,不然没有权限
然后输入shutdown关闭服务
redis-server redisconfigs/redis.config打开服务
编写测试代码
lettuce
springboot2.x就把底层的redis操作从jedis改成了lettuce,因为jedis是线程不安全的
通过 redisTemplate.getConnectionFactory().getConnection(); 获得connection对象操作
Redis持久化
为什么要进行持久化操作?
Redis是内存数据库,断电就会丢失所有数据,所以必须有持久化操作
两种持久化操作
rdb(redis database)默认开启
触发规则
save规则
flushall命令
退出redis
恢复rdb文件
把dump.rbd放在启动目录就可以了,redis启动时会自动检查
优点
适合大规模数据恢复
对数据的完整性要求不高
缺点
需要一定的时间间隔操作,如果期间redis宕机,最后一次数据无法保存
fork子进程占用一定空间
aof(append only file)默认关闭
机制
记录每一次的写操作,数据恢复时重新运行这些命令,重构数据
开启方法
redis.conf中把appendonly改成yes
Redis发布订阅
可以做好友动态、聊天室等等
实际使用
先订阅频道
然后新开窗口往频道里发布内容
此时发现之前订阅了xiaoye这个频道的窗口自动监听了频道消息
Redis主从复制
主要作用
实现数据热备份,是数据持久化的另一种操作
故障恢复,当某一服务挂了后,可以从节点进行数据恢复
负载均衡,主机写,从机读,分担负载
高可用基石,主从复制是哨兵机制和集群的基础
适用场景
单台Redis的最大使用内存不要超过20G
建议至少一主二从的配置,一主一从哨兵机制会出错
环境搭建
⭐Redis默认自己就是主库,所以我们只需要配置从库
查看当前库的信息
info replication
复制配置文件,redis.conf
修改配置文件
注释bind绑定ip
/bind搜索
端口
/port搜索
守护线程开启
/daemonize搜索
pid修改
/pidfile搜索
日志文件修改
/logfile搜索
dbfilename修改
/dbfilename搜索
以配置文件启动redis,查看后台进程
后台进程
配置从机,找老大
在从机中配置
上面认老大的slaveof是命令式的,一次性的,我们最好使用配置文件配置
复制原理
全量复制
增量复制
从机一旦连接,就会向主机发送一个sync同步命令,主机就会发送全部数据给从机,完成同步
从机连接成功后会继续复制主机新增/改的值
哨兵模式
哨兵进程检测redis服务进程,会间隔进行心跳检测确定redis服务进程是否存活
一旦主机挂机了,就会进行故障转移---failover,重新选取主机
就算挂掉的主机回来了,也只能作为从机继续服务了
使用
编写sentinel.conf
sentinel monitor [名称] 127.0.0.1(主机地址) 6379(主机端口) 1(开启主机选举)
启动哨兵进程
redis-sentinel sentinel.conf
主机挂掉后
哨兵机制会在下次心跳检测到主机挂掉,故障转移,选取新主机
之前的主机复活后
就算复活了,也只能当从机了,一旦失去不再来,除非当前主机挂掉重新选取才有机会
基于主从复制,所有的主从复制的优点它都有
主从自动切换,故障可以转移,系统可用性更好
不好在线扩容
哨兵模式的配置十分麻烦
缓存穿透和雪崩
缓存穿透
现象
请求redis不存在的缓存数据,导致请求全部打到mysql数据库,形成缓存穿透
例子
恶意攻击
解决方案
布隆过滤器
把请求存起来,存空
缓存击穿
某个key非常热点,承担了超高并发,当这个key失效,持续的超高并发请求就会达到mysql数据库上
微博热搜宕机
设置热点数据永不过期
加互斥锁
大量请求在缓存中失效,全部打进mysql数据库
多设置几台redis服务器
限流降级,保证服务可用
设置缓存时间随机,失效均匀
0 条评论
回复 删除
下一页