Redis
安装
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
//scl enable devtoolset-9 bash
echo “source /opt/rh/devtoolset-9/enable” >>/etc/profile
cd /usr/local/bin
cp /opt/redis-6.2.1/redis.conf zconfig/
systemctl status firewalld
systemctl start firewalld
查看指定端口是否已开放
firewall-cmd --query-port=3690/tcp
提示 yes,表示开启;no表示未开启
添加指定需要开放的端口:
firewall-cmd --add-port=3690/tcp --permanent
重载入添加的端口:
firewall-cmd --reload
测试有效!
![(Redis.assets/image-20210412091937193.png)
从系统维度说,要了解 Redis 各项关键技术的设计原理,并掌握一些系统设计规范,比如 run-to-complete 模型、epoll 网络模型,以便应用到后续的系统开发中。但 Redis 的知识点很零碎,所以,可以按照“三大主线”为它们分类:
- 高性能主线,包括线程模型、数据结构、持久化、网络框架;
- 高可靠主线,包括主从复制、哨兵机制;
- 高可扩展主线,包括数据分片、负载均衡。
在应用维度上,可以按 “应用场景驱动”和“典型案例驱动”两种方式学习,一个是“面”的梳理,一个是“点”的掌握。
五大数据类型使用场景
默认安装路径
/user/local/bin
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dSdu1X3M-1619079935446)(Redis.assets/image-20210326130319401.png)]
-
将配置文件重新拷贝一份,并修改config使用后台启动[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HtuJqk2t-1619079935448)(Redis.assets/image-20210326130824405.png)]
-
启动要使用后台启动:
redis-server redis.conf ---> redis-cli -p 6379
-
查看redis进程
ps -ef|grep redis
-
关闭redis shutdown —> exit
命令不区分大小写,key区分大小写
help@名词
String
商品编号,订单编号 INCR自增生成
是否喜欢的文章
list
有序有重复
微信文章公众号
hash
redis中的哈希对应于java中的什么数据结构
Map<String,Map<Object,Object>>
使用场景
购物车早期,中小厂使用
set有序集合
使用场景:
- 小程序抽奖
- 共同好友,标签
zset(sorted tree)
使用场景
- 热搜
- 商品排序,按照销售量,按照搜索,按照距离
bitmap
只有0,1两个状态
HyperLoglogs
GEO
Stream
事务:
不保证原子性
没有隔离级别,所有的命令在事务中并没有直接被执行而是在发起命令的时候才会在执行,先进入队列
- 开启事务: multi
- 命令入队
- 执行事务:exec
锁:Redis可以实现乐观锁
分布式锁:
区别
- JVM层面的加锁 单机版的锁
- 分布式微服务架构,拆分后,为了避免冲突和数据故障加入的一种锁
实现方案
- Mysql实现
- zookeper
- Redis
之前,String+setnx 自己手写需要setnx + lua脚本
现在使用RedisCluster — Redisson
-
单机版加锁
- sychronized—代码块不完成,不结束,请求积压—不见不散
- lock-Renentrentlock
- trylock----过时不候,规避一直等待
不见不散
过时不候
-
ngix 反向代理和负载均衡
-
加上setnx分布式锁
实现方式:setIfAbsent() == setnx操作
@GetMapping("/buy_goods") public String buy_Goods() { String value = UUID.randomUUID().toString() + Thread.currentThread().getName();//标识符,不可重复 Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(REDIS_LOCK, value);//缺席 nx if not exist == setnx if(!flag){ return "强锁失败"; } String result = stringRedisTemplate.opsForValue().get("goods:001"); // == get key 看看库存的数量够不够 int goodNumber = result == null ? 0 : Integer.parseInt(result); //判断产品是否为null if (goodNumber > 0) { int realNumber = goodNumber - 1; stringRedisTemplate.opsForValue().set("goods:001", String.valueOf(realNumber)); System.out.println("成功买到商品,库存还剩下 : " + realNumber + "件" + "\t 服务提供端口为 " + serverPort); stringRedisTemplate.delete(REDIS_LOCK); return "成功买到商品,库存还剩下 : " + realNumber + "件" + "\t 服务提供端口为 " + serverPort; } else { System.out.println("商品已经售罄/活动结束/调用超时" + "\t 服务提供端口:" + serverPort); return "商品已经售罄/活动结束/调用超时" + "\t 服务提供端口:" + serverPort; } }
-
业务操作出现异常无法解锁----finally代码块强制解锁
-
部署了微服务jar包的机器挂了,代码层面根本没有走到finally这块, 没办法保证解锁,这个key没有被删除,需要加入一个过期时间限定key
解决方法: 把key设置超时时间–expire
没有保证原子性:加锁和设置过期时间没有保证原子性
-
设置key+过期时间分开了,必须要合并成一行具备原子性
解决方法:
Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(REDIS_LOCK, value,10L,TimeUnit.SECONDS);
-
张冠李戴,删除了别人的锁
只能删除自己得锁—进行value判断
-
finally块的判断+del删除操作不是原子性的
LUA脚本
不可以用LUA脚本—redis自身事务
-
确保redisLock过期时间大于业务执行时间的问题
redis分布式锁续期----
-
集群+CAP 对比zookeeper
redis ap,主节点写入,从节点还没复制完成就宕机了,早成数据不一致,从机上位,主机降级
zookeeper没有异步复制丢失,并发性下降
-
规避缓存续期和数据不一致性,Redlock之Redission实现
总结:
redis集群环境下,我们自己写的也不OK, 直接上RedLock之Redisson落地实现
Redisson lock/unlock
单点部署什么问题,怎么解决
集群模式,比如主从模式,有没有什么问题
介绍一下Redlock,介绍一下Redission
了,早成数据不一致,从机上位,主机降级
zookeeper没有异步复制丢失,并发性下降
- 规避缓存续期和数据不一致性,Redlock之Redission实现
总结:
redis集群环境下,我们自己写的也不OK, 直接上RedLock之Redisson落地实现
Redisson lock/unlock
单点部署什么问题,怎么解决
集群模式,比如主从模式,有没有什么问题
介绍一下Redlock,介绍一下Redission
Redis分布式锁如何续期,看门狗知道吗