|
|
|
|
<h1><center>Redis扩展部分</center></h1>
|
|
|
|
|
|
|
|
|
|
作者:行癫(盗版必究)
|
|
|
|
|
|
|
|
|
|
------
|
|
|
|
|
|
|
|
|
|
## 一:分布式锁简介
|
|
|
|
|
|
|
|
|
|
#### 1.简介
|
|
|
|
|
|
|
|
|
|
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁
|
|
|
|
|
|
|
|
|
|
分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
|
|
|
|
|
|
|
|
|
|
![image-20231007214715309](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20231007214715309.png)
|
|
|
|
|
|
|
|
|
|
#### 2.分布式锁满足的条件
|
|
|
|
|
|
|
|
|
|
可见性:多个线程都能看到相同的结果,注意:这个地方说的可见性并不是并发编程中指的内存可见性,只是说多个进程之间都能感知到的变化
|
|
|
|
|
|
|
|
|
|
互斥:互斥是分布式锁的最基本的条件,使得程序串行执行
|
|
|
|
|
|
|
|
|
|
高可用:程序不易崩溃,时时刻刻都保证较高的可用性
|
|
|
|
|
|
|
|
|
|
高性能:由于加锁本身就让性能降低,所有对于分布式锁本身需要他就较高的加锁性能和释放锁性能
|
|
|
|
|
|
|
|
|
|
安全性:安全也是程序中必不可少的一环
|
|
|
|
|
|
|
|
|
|
![image-20231007215001368](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20231007215001368.png)
|
|
|
|
|
|
|
|
|
|
#### 3.常见的分布式锁
|
|
|
|
|
|
|
|
|
|
Mysql:本身就带有锁机制,但是由于mysql性能本身一般,所以采用分布式锁的情况下,其实使用mysql作为分布式锁比较少见
|
|
|
|
|
|
|
|
|
|
Redis:作为分布式锁是非常常见的一种使用方式,现在企业级开发中基本都使用redis或者zookeeper作为分布式锁,利用setnx这个方法,如果插入key成功,则表示获得到了锁,如果有人插入成功,其他人插入失败则表示无法获得到锁,利用这套逻辑来实现分布式锁
|
|
|
|
|
|
|
|
|
|
Zookeeper:也是企业级开发中较好的一个实现分布式锁的方案
|
|
|
|
|
|
|
|
|
|
![image-20231007215146879](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20231007215146879.png)
|
|
|
|
|
|
|
|
|
|
#### 3.设置分布式锁
|
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
[root@ xingdian ~]# redis-cli
|
|
|
|
|
127.0.0.1 > SET name xingdian NX EX 10
|
|
|
|
|
# 添加锁 NX是互斥的 EX设置超时时间
|
|
|
|
|
127.0.0.1 > SETNX class cloud
|
|
|
|
|
# 使用SETNX创建互斥锁
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
删除
|
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
[root@ xingdian ~]# redis-cli
|
|
|
|
|
127.0.0.1 > DEL key
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
注意:
|
|
|
|
|
|
|
|
|
|
在获取锁时加入过期时间;可以避免服务宕机,然后死锁
|
|
|
|
|
|
|
|
|
|
添加释放锁需要判断是否是当前线程,避免锁误删操作
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 5.核心思路
|
|
|
|
|
|
|
|
|
|
我们利用redis 的setNx方法,当有多个线程进入时,我们就利用该方法,第一个线程进入时,redis 中就有这个key 了,返回了1,如果结果是1,则表示他抢到了锁,那么他去执行业务,然后再删除锁,退出锁逻辑,没有抢到锁的,等待一定时间后重试即可
|
|
|
|
|
|
|
|
|
|
<img src="https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20231007220404622.png" alt="image-20231007220404622" style="zoom:50%;" />
|
|
|
|
|
|
|
|
|
|
#### 6.锁的基本接口
|
|
|
|
|
|
|
|
|
|
<img src="https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20231007220504083.png" alt="image-20231007220504083" style="zoom:50%;" />
|
|
|
|
|
|
|
|
|
|
## 二:Redis故障的排查思路
|
|
|
|
|
|
|
|
|
|
1.了解清楚业务数据流是怎么样的
|
|
|
|
|
|
|
|
|
|
2.结合 Redis 监控查看 QPS、缓存命中率、内存使用率等信息
|
|
|
|
|
|
|
|
|
|
3.确认机器层面的资源是否有异常
|
|
|
|
|
|
|
|
|
|
4.故障时及时上机,使用 redis-cli monitor 打印出操作日志,然后分析
|
|
|
|
|
|
|
|
|
|
5.和研发沟通,确认是否有大 Key 在堵塞(大 Key 也可以在日常的巡检中获得)
|
|
|
|
|
|
|
|
|
|
6.和组内同事沟通,确实是否有误操作
|
|
|
|
|
|
|
|
|
|
7.和运维同事、研发一起排查流量是否正常,是否存在被刷的情况
|
|
|
|
|
|
|
|
|
|
## 三:常见的运维故障
|
|
|
|
|
|
|
|
|
|
1.超过内存使用后,部分数据被删除——这个有删除策略的,选择适合自己的即可
|
|
|
|
|
|
|
|
|
|
2.没开持久化,却重启了实例,数据全掉——记得非缓存的信息需要打开持久化
|
|
|
|
|
|
|
|
|
|
3.RDB的持久化需要vm.overcommit_memory=1,否则会有持久化失败
|
|
|
|
|
|
|
|
|
|
4.没有持久化情况下,主从,主重启太快,从还没认为主挂的情况下,从会清空自己的数据——人为重启主节点前,先关闭从节点的同步
|
|
|
|
|
|
|
|
|
|
## 四:常见面试题
|
|
|
|
|
|
|
|
|
|
1.Redis是什么?它有哪些主要特性?
|
|
|
|
|
|
|
|
|
|
答案:Redis是一种基于内存的键值存储系统,具有高性能、可持久化、支持多种数据类型和丰富的命令集等特性
|
|
|
|
|
|
|
|
|
|
2.Redis的数据类型有哪些?它们的优缺点是什么?
|
|
|
|
|
|
|
|
|
|
答案:Redis支持多种数据类型,包括String、Hash、List、Set和Sorted Set等
|
|
|
|
|
|
|
|
|
|
String:支持多种操作,如字符串的存储、查找和删除等。但是,不能用于复杂的数据结构
|
|
|
|
|
|
|
|
|
|
Hash:支持键值对的存储,可以用于存储复杂的数据结构。但是,查找和删除操作比String慢
|
|
|
|
|
|
|
|
|
|
List:支持在头部和尾部添加和删除元素,可以用于实现队列和栈等数据结构。但是,插入和删除元素比String慢
|
|
|
|
|
|
|
|
|
|
Set:支持存储不重复的元素,可以用于去重和集合运算等。但是,插入和删除元素比String慢
|
|
|
|
|
|
|
|
|
|
Sorted Set:支持存储有序的元素,可以用于实现排行榜等场景。但是,插入和删除元素比String慢
|
|
|
|
|
|
|
|
|
|
3.Redis如何实现数据持久化?有哪些持久化策略?
|
|
|
|
|
|
|
|
|
|
答案:Redis提供了多种数据持久化策略,包括RDB(Redis Database)和AOF(Append Only File)等。RDB是通过将Redis内存中的数据定期写入到磁盘上来实现数据持久化的。AOF是通过将Redis的写命令追加到一个日志文件中来实现数据持久化的。RDB的优点是写入速度较快,但是数据恢复时间较长;AOF的优点是数据恢复速度快,但是写入速度较慢
|
|
|
|
|
|
|
|
|
|
4.Redis的复制机制是如何工作的?如何配置复制?
|
|
|
|
|
|
|
|
|
|
答案:Redis的复制机制是通过主从复制来实现的。主从复制是将主节点的数据同步到从节点上,以实现数据的备份和冗余。在配置复制时,需要设置主节点和从节点之间的网络连接参数,如主机名、端口号和密码等
|
|
|
|
|
|
|
|
|
|
5.Redis的集群是如何工作的?如何配置集群?
|
|
|
|
|
|
|
|
|
|
答案:Redis的集群是通过将多个Redis节点组织成一个分布式系统来实现的。在配置集群时,需要设置节点之间的网络连接参数,如主机名、端口号和密码等。此外,还需要设置集群的配置参数,如节点ID、分片数量和哈希槽分布等
|
|
|
|
|
|
|
|
|
|
6.Redis的安全性如何?如何保护Redis免受攻击?
|
|
|
|
|
|
|
|
|
|
答案:Redis的安全性主要依赖于密码保护和数据加密等机制。在配置Redis时,可以通过设置密码来限制对Redis的访问。此外,还可以通过使用TLS/SSL等加密协议来保护Redis的数据传输安全
|
|
|
|
|
|
|
|
|
|
7.Redis的性能如何?如何优化Redis的性能?
|
|
|
|
|
|
|
|
|
|
答案:Redis的性能主要依赖于内存管理和网络通信等机制
|
|
|
|
|
|
|
|
|
|
提高Redis内存使用效率,如减少不必要的内存消耗、优化数据结构和算法等
|
|
|
|
|
|
|
|
|
|
优化网络通信性能,如使用更高效的协议、提高网络带宽和降低网络延迟等
|
|
|
|
|
|
|
|
|
|
提高Redis的并发性能,如增加Redis实例的数量、使用更高效的数据库引擎和缓存策略等
|
|
|
|
|
|
|
|
|
|
8.Redis的使用场景有哪些?如何选择合适的Redis部署方式?
|
|
|
|
|
|
|
|
|
|
答案:Redis适用于各种高性能的数据存储场景,如缓存、实时分析、消息队列和分布式锁等
|
|
|
|
|
|
|
|
|
|
数据量:如果数据量较小,可以选择单机部署;如果数据量较大,可以选择分布式部署
|
|
|
|
|
|
|
|
|
|
读写性能:如果读性能较高,可以选择使用缓存来提高性能;如果写性能较高,可以选择使用队列来提高性能
|
|
|
|
|
|
|
|
|
|
可用性:如果需要高可用性,可以选择使用主从复制和集群等部署方式
|
|
|
|
|
|
|
|
|
|
9.Redis在实际应用中常见的问题有哪些?如何解决这些问题?
|
|
|
|
|
|
|
|
|
|
数据丢失:由于网络故障、硬件故障或操作错误等原因,可能导致Redis的数据丢失
|
|
|
|
|
|
|
|
|
|
磁盘空间不足:由于数据量过大或缓存策略不当等原因,可能导致Redis的磁盘空间不足
|
|
|
|
|
|
|
|
|
|
性能瓶颈:由于网络延迟、内存使用率过高或数据库引擎不适用等原因,可能导致Redis的性能瓶颈
|
|
|
|
|
|
|
|
|
|
安全问题:由于密码设置不当、网络攻击或恶意软件等原因,可能导致Redis的安全问题
|
|
|
|
|
|
|
|
|
|
在解决这些问题时,可以采取以下几种措施:
|
|
|
|
|
|
|
|
|
|
使用数据备份和恢复策略,如RDB和AOF等,防止数据丢失
|
|
|
|
|
|
|
|
|
|
优化Redis的缓存策略和数据结构,如使用LRU和TTL等,减少磁盘空间的使用
|
|
|
|
|
|
|
|
|
|
优化Redis的网络通信和数据库引擎,如使用更高效的协议和数据库引擎等,提高Redis的性能
|
|
|
|
|
|
|
|
|
|
使用安全策略和工具,如设置强密码、使用TLS/SSL和安装安全软件等,保护Redis的安全
|
|
|
|
|
|
|
|
|
|
10.关于redis的雪崩、击穿、穿透(见文档)
|