Redis 集群:引领企业级 NoSQL 数据库新潮流

一 、关系型数据库和NoSQL数据库

在当今的数据库领域,关系型数据库和非关系型数据库都占据着重要的地位。

关系型数据库

关系型数据库是建立在关系模型基础上的数据库,它通过表与表之间的关系来存储和管理数据。

  1. 特点

    • 数据结构清晰:以二维表的形式组织数据,表中的每一行代表一个实体,每一列代表实体的一个属性。这种结构使得数据的逻辑关系明确,易于理解和维护。
    • 数据一致性高:支持事务处理,可以确保数据的完整性和一致性。在事务中,一组操作要么全部成功,要么全部失败,不会出现部分成功部分失败的情况。
    • 支持复杂查询:可以使用 SQL 语言进行复杂的查询操作,包括多表连接、子查询、聚合函数等。这使得用户能够方便地从大量数据中提取所需的信息。
    • 成熟稳定:关系型数据库已经发展了几十年,技术成熟,有大量的工具和技术支持。许多企业级应用都依赖于关系型数据库来存储关键业务数据。
  2. 常见的关系型数据库

    • MySQL:一款开源的关系型数据库管理系统,广泛应用于 Web 应用开发。它具有高性能、可靠性和易用性,支持多种操作系统。
    • Oracle:一款功能强大的商业关系型数据库管理系统,适用于大型企业级应用。它提供了丰富的功能和工具,包括高可用性、安全性和性能优化。
    • SQL Server:微软推出的关系型数据库管理系统,与 Windows 操作系统紧密集成。它提供了良好的性能和易用性,适用于中小企业和部门级应用。

非关系型数据库(NoSQL 数据库)

非关系型数据库是相对于关系型数据库而言的,它不使用传统的关系模型来存储数据,而是采用了不同的数据模型。

  1. 特点

    • 灵活性高:数据模型灵活多样,可以根据不同的应用需求选择合适的数据模型。例如,文档数据库以文档的形式存储数据,键值数据库以键值对的形式存储数据,图数据库以图的形式存储数据等。
    • 可扩展性强:易于水平扩展,可以通过添加更多的服务器来提高数据库的性能和容量。这使得非关系型数据库能够处理大规模的数据和高并发的访问。
    • 高性能:通常采用分布式架构,能够快速地读写数据。一些非关系型数据库还支持内存存储,进一步提高了数据的访问速度。
    • 适用于特定场景:非关系型数据库在一些特定的场景下表现出色,例如大数据处理、实时数据分析、内容管理系统等。
  2. 常见的非关系型数据库

    • MongoDB:一款文档数据库,以 JSON 格式的文档存储数据。它具有灵活的数据模型、高可扩展性和高性能,适用于 Web 应用、移动应用和大数据处理等场景。
    • Redis:一款内存键值数据库,支持多种数据结构,如字符串、列表、集合、有序集合等。它具有高性能、低延迟和丰富的功能,适用于缓存、消息队列、实时数据分析等场景。
    • Cassandra:一款分布式列族数据库,具有高可扩展性、高可用性和高性能。它适用于大规模数据存储和高并发访问的场景,如互联网应用、金融服务等。

二、为什么还要用NoSQL数据库

在当今的数据库领域中,虽然关系型数据库已经非常成熟且广泛应用,但 NoSQL 数据库依然有其不可替代的地位,主要原因如下:

灵活性与可扩展性

  1. 数据模型灵活

    • 关系型数据库通常要求数据具有严格的模式(schema),在进行数据存储之前,需要预先定义好表结构,包括字段名称、数据类型、长度等。这在某些情况下可能会限制数据的存储和处理方式。
    • 而 NoSQL 数据库的数据模型更加灵活。例如,文档型 NoSQL 数据库可以存储半结构化的数据,如 JSON 或 XML 格式的文档,无需预先定义严格的模式。这使得在面对不断变化的业务需求时,能够更快速地适应数据结构的变化,无需进行繁琐的表结构修改。
    • 键值型 NoSQL 数据库则以简单的键值对形式存储数据,对于一些只需要快速存储和检索特定值的数据场景非常适用。
  2. 可扩展性强

    • 随着业务的发展,数据量和访问量不断增加,数据库的可扩展性变得至关重要。关系型数据库在扩展方面往往面临一些挑战,如垂直扩展成本高,水平扩展较为复杂。
    • NoSQL 数据库通常具有良好的可扩展性,可以轻松地进行水平扩展。通过添加更多的服务器节点,可以线性地提高数据库的存储容量和处理能力,以满足不断增长的业务需求。

高性能

  1. 读写性能优势

    • NoSQL 数据库在设计上通常更注重性能优化,尤其是在大规模数据存储和高并发访问的情况下。例如,内存型 NoSQL 数据库将数据存储在内存中,可以实现极快的数据读写速度,非常适合对响应时间要求极高的应用场景,如实时数据分析、缓存等。
    • 一些 NoSQL 数据库还采用分布式架构,将数据分散存储在多个节点上,并行处理读写请求,进一步提高了数据库的性能。
  2. 适应大数据处理

    • 在大数据时代,数据量呈爆炸式增长,传统的关系型数据库在处理大规模数据时可能会遇到性能瓶颈。NoSQL 数据库能够更好地应对大数据的挑战,例如,分布式 NoSQL 数据库可以处理海量的数据,并且能够快速地进行数据的存储、检索和分析。

特定应用场景需求

  1. 社交网络和实时应用

    • 在社交网络应用中,用户之间的关系复杂,数据量大且变化频繁。NoSQL 数据库中的图数据库非常适合处理这种复杂的关系数据,能够高效地进行关系查询和分析。
    • 对于实时应用,如即时通讯、在线游戏等,需要快速地处理和响应大量的并发请求。NoSQL 数据库的高性能和可扩展性能够满足这些应用的需求。
  2. 内容管理系统和日志分析

    • 内容管理系统通常需要存储和管理各种类型的非结构化数据,如图像、视频、文档等。NoSQL 数据库的文档型数据库可以方便地存储和检索这些非结构化数据。
    • 在日志分析场景中,需要快速地处理大量的日志数据,进行实时分析和查询。NoSQL 数据库的分布式架构和高性能能够满足日志分析的需求。

三、RDBMSNOSQL****的特点及优缺点

RDBMS(关系型数据库管理系统)的特点、优点和缺点

特点

  1. 数据结构清晰:以表格形式存储数据,表之间通过关系(如外键)相互关联,数据的逻辑结构明确。
  2. 数据一致性高:支持事务处理,确保数据的完整性和一致性,对数据的修改遵循严格的 ACID(原子性、一致性、隔离性、持久性)原则。
  3. 标准化查询语言:使用 SQL(结构化查询语言)进行数据查询和操作,语法规范,易于学习和使用。
  4. 成熟稳定:经过多年的发展和完善,技术成熟,有大量的工具和技术支持。

优点

  1. 数据可靠性强:由于严格的数据一致性保证,数据的准确性和可靠性较高,适合存储关键业务数据。
  2. 复杂查询支持好:可以进行多表连接、子查询等复杂查询操作,能够满足复杂的业务需求。
  3. 数据安全性高:提供了完善的安全机制,如用户权限管理、数据加密等,保障数据的安全。
  4. 适合事务处理场景:对于需要保证事务完整性的业务场景,如银行交易、订单处理等,关系型数据库表现出色。

缺点

  1. 扩展性有限:在面对大规模数据和高并发访问时,扩展成本较高,往往需要进行垂直扩展(升级硬件)或复杂的水平扩展(分库分表)。
  2. 灵活性不足:数据模式固定,修改表结构可能会影响到现有数据和应用程序,对于快速变化的业务需求适应性较差。
  3. 性能瓶颈:在处理大量非结构化数据或高并发读写操作时,性能可能会受到影响。

NoSQL(非关系型数据库)的特点、优点和缺点

特点

  1. 数据模型灵活:支持多种数据模型,如键值对、文档、列族、图等,可以根据不同的应用场景选择合适的数据模型。
  2. 可扩展性强:易于水平扩展,通过添加更多的节点可以轻松应对大规模数据和高并发访问。
  3. 高性能:通常采用分布式架构,能够快速地进行数据读写操作,尤其适合对性能要求较高的实时应用场景。
  4. 支持非结构化数据:能够存储和处理各种类型的非结构化数据,如图像、视频、文档等。

优点

  1. 灵活性高:数据模式不固定,可以随时添加或删除字段,适应快速变化的业务需求。
  2. 可扩展性好:能够轻松应对大数据和高并发的挑战,随着业务的增长可以方便地进行扩展。
  3. 高性能读写:在处理大规模数据和高并发访问时,性能优势明显,能够快速响应请求。
  4. 适合特定场景:对于一些特定的应用场景,如社交网络、实时分析、内容管理等,NoSQL 数据库具有独特的优势。

缺点

  1. 数据一致性较弱:大多数 NoSQL 数据库不支持严格的事务处理,数据一致性相对较低,可能会出现数据不一致的情况。
  2. 查询语言不统一:不同类型的 NoSQL 数据库使用不同的查询语言,学习成本较高,且缺乏统一的标准。
  3. 成熟度较低:相比关系型数据库,NoSQL 数据库的发展历史较短,技术成熟度相对较低,可能存在一些稳定性和可靠性问题。
  4. 数据安全性有待提高:在数据安全方面,NoSQL 数据库的安全机制相对较弱,需要额外的措施来保障数据安全。

四、Remote Dictionary Server****简介

Remote Dictionary Server(远程字典服务),通常简称 Redis,是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库。

主要特点

  1. 高性能

    • Redis 是内存数据库,数据存储在内存中,这使得它能够以极快的速度进行读写操作。对于需要快速响应的应用场景,如缓存系统、实时数据分析等,Redis 的高性能是一个巨大的优势。
    • 它采用单线程模型,避免了多线程竞争带来的开销,同时通过异步 I/O 和事件驱动机制,高效地处理大量并发连接。
  2. 丰富的数据结构

    • Redis 不仅仅是一个简单的键值存储数据库,它支持多种复杂的数据结构,如字符串、哈希表、列表、集合、有序集合等。这些数据结构为开发者提供了更多的选择,可以根据不同的应用需求灵活地存储和操作数据。
    • 例如,列表可以用于实现消息队列,集合可以用于存储唯一的元素,有序集合可以用于实现排行榜等功能。
  3. 持久化机制

    • Redis 提供了两种持久化方式:RDB(Redis Database)和 AOF(Append Only File)。
    • RDB 是一种快照方式,它将某一时刻的数据库状态保存到一个磁盘文件中。这种方式在恢复数据时速度较快,但可能会丢失部分数据。
    • AOF 则是将所有的写操作记录到一个追加日志文件中,通过回放日志文件来恢复数据。这种方式可以保证数据的完整性,但恢复速度相对较慢。
  4. 主从复制和高可用

    • Redis 支持主从复制功能,可以将一个 Redis 实例的数据同步到多个从实例中。主从复制可以实现数据的备份和读写分离,提高系统的可用性和性能。
    • 此外,Redis 还可以通过 Sentinel(哨兵)和 Cluster(集群)等机制实现高可用。Sentinel 可以监控 Redis 主从实例的状态,当主实例出现故障时,自动进行故障转移。Cluster 则可以将数据分布到多个节点上,实现自动分片和高可用。

应用场景

  1. 缓存

    • Redis 最常见的应用场景之一是作为缓存。将经常访问的数据存储在 Redis 中,可以大大减少对后端数据库的访问压力,提高系统的响应速度。例如,在 Web 应用中,可以将热点数据、页面缓存等存储在 Redis 中,以提高用户体验。
  2. 消息队列

    • 利用 Redis 的列表数据结构,可以实现简单的消息队列功能。生产者将消息推送到 Redis 列表中,消费者从列表中取出消息进行处理。这种方式适用于一些对实时性要求不高的场景,如异步任务处理、日志收集等。
  3. 排行榜

    • Redis 的有序集合可以方便地实现排行榜功能。例如,可以将用户的得分作为有序集合的分值,用户 ID 作为成员,实时更新用户的排名。在游戏、社交等领域,排行榜是一种常见的功能需求。
  4. 分布式锁

    • 在分布式系统中,需要一种机制来保证多个节点对共享资源的互斥访问。Redis 可以通过 SETNX 命令实现分布式锁。当一个节点获取到锁时,其他节点必须等待锁释放后才能获取。这种方式可以有效地避免分布式系统中的资源竞争问题。

5、Session 共享
1.常见于web 集群中的 Tomcat 或者 PHP 中多 web 服务器 session 共享
6、计数器
1.访问排行榜、商品浏览数等和次数相关的数值统计场景
7、微博 / 微信社交场合
1.共同好友,粉丝数 , 关注 , 点赞评论等
8、消息队列
1.ELK的日志缓存、部分业务的订阅发布系统
9、地理位置
1.基于GEO( 地理信息定位 ), 实现摇一摇 , 附近的人 , 外卖等功能

官网:Redis - The Real-time Data Platform

Redis单线程

Redis 是单线程模型,这意味着它在执行所有操作时只使用一个线程。

单线程的优势

避免线程切换和竞争开销
  • 在多线程环境中,线程切换会带来一定的开销。操作系统需要保存当前线程的状态,并切换到另一个线程,然后在适当的时候恢复原来的线程状态。这个过程会消耗一定的 CPU 时间和资源。
  • 而 Redis 单线程模型避免了线程切换的开销,使得它能够更高效地利用 CPU 资源。同时,由于只有一个线程在执行操作,也不存在多线程之间的竞争问题,减少了锁的使用和竞争带来的性能损耗。
简单的代码实现和维护
  • 单线程模型使得 Redis 的代码实现相对简单。开发者不需要考虑多线程并发带来的复杂问题,如线程安全、死锁等。这降低了代码的复杂度,提高了代码的可读性和可维护性。
高效的内存管理
  • Redis 在内存管理方面也受益于单线程模型。由于只有一个线程在操作内存,不需要考虑多线程环境下的内存同步问题,可以更高效地进行内存分配和释放。同时,Redis 采用了一些优化的内存管理策略,如预分配、内存池等,进一步提高了内存的使用效率。

缓存的实现流程

数据更新操作流程

数据读操作流程

五、Redis****的安装

官方下载地址: Index of /releases/ (redis.io)

源码安装

上传需要的安装包

解压缩

安装编译工具

root@redis-node1 redis-7.4.0\]# yum install make gcc initscripts-10.11.6-1.el9.x86_64 -y #### 执行编译命令 \[root@redis-node1 redis-7.4.0\]# make \&\& make install ![](https://i-blog.csdnimg.cn/direct/6986d0353e7a411b9aa0ee62932b419d.png) #### 启动Redis ![](https://i-blog.csdnimg.cn/direct/29931e3a7ea2488ab643e1e432c99b56.png) 提示系统使用的是systemd的初始化方式 #### 解决报错问题 \[root@redis-node1 utils\]# vim install_server.sh 注意将这几行注释 ![](https://i-blog.csdnimg.cn/direct/2f9dd455fbb3462199f05895ea64afde.png) ![](https://i-blog.csdnimg.cn/direct/8f70eef01a254a2ebf3d04e7b678a699.png) > \[root@redis-node1 utils\]# ./install_server.sh > > Welcome to the redis service installer > > This script will help you easily set up a running redis server > > This systems seems to use systemd. > > Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry! > > \[root@redis-node1 utils\]# vmi install_server.sh > > bash: vmi: command not found... > > Similar command is: 'vim' > > \[root@redis-node1 utils\]# vim install_server.sh > > \[root@redis-node1 utils\]# ./install_server.sh > > Welcome to the redis service installer > > This script will help you easily set up a running redis server > > Please select the redis port for this instance: \[6379\] #端口号 > > Selecting default: 6379 > > Please select the redis config file name \[/etc/redis/6379.conf\] #配置文件 > > Selected default - /etc/redis/6379.conf > > Please select the redis log file name \[/var/log/redis_6379.log\] #日志 > > Selected default - /var/log/redis_6379.log > > Please select the data directory for this instance \[/var/lib/redis/6379\] #数据目录 > > Selected default - /var/lib/redis/6379 > > Please select the redis executable path \[/usr/local/bin/redis-server\] #命令路径 > > Selected config: > > Port : 6379 > > Config file : /etc/redis/6379.conf > > Log file : /var/log/redis_6379.log > > Data dir : /var/lib/redis/6379 > > Executable : /usr/local/bin/redis-server > > Cli Executable : /usr/local/bin/redis-cli > > Is this ok? Then press ENTER to go on or Ctrl-C to abort. > > Copied /tmp/6379.conf =\> /etc/init.d/redis_6379 > > Installing service... > > Successfully added to chkconfig! > > Successfully added to runlevels 345! > > Starting Redis server... > > Installation successful! #### 配置redis \[root@redis-node1 utils\]# vim /etc/redis/6379.conf ![](https://i-blog.csdnimg.cn/direct/127649c054f1430d8c0e0cf8b0a06abe.png) 关闭保护模式 ![](https://i-blog.csdnimg.cn/direct/1e9b512cfeb04addbc1c01c40351c2ad.png) 再重启 ![](https://i-blog.csdnimg.cn/direct/37dd347948a141f589b9918154b8bb86.png) ![](https://i-blog.csdnimg.cn/direct/296d1a6125e44a0fbe0fd3d35e1a4893.png) 查看信息 ![](https://i-blog.csdnimg.cn/direct/52edc1ffd5d84684b4711c0d5dcbcd44.png) ## 六、**Redis****的基本操作** ![](https://i-blog.csdnimg.cn/direct/23044680cf214d738aeee2cffa69af25.png) ### 查看配置 ![](https://i-blog.csdnimg.cn/direct/2f259fa6435e435f987b6df9ce49bf5d.png) ### 写入和读取数据(如果没有设定数据过期时间会一直存在, /var/lib/redis/6379/dump.rdb内存快照中 ) ![](https://i-blog.csdnimg.cn/direct/2d456dbb03ae4e1081f089d61e2c4f65.png) ![](https://i-blog.csdnimg.cn/direct/318e1cedc0fc4ffabf8b5c8a3813f553.png) ### 选择数据库 redisa中有0-15个数据库 ![](https://i-blog.csdnimg.cn/direct/a84cb6c57a5c42c0bdbed44b64121f46.png) ### 移动数据 ![](https://i-blog.csdnimg.cn/direct/b9de5f4ab90a4975a11c53b88fd10909.png) ### 改变键名 ![](https://i-blog.csdnimg.cn/direct/0748419e702742b68baf32b94651a0f9.png) ### 设定数据过期时间 ![](https://i-blog.csdnimg.cn/direct/78baf54dd5dc410f9c4d4998aca106d4.png) ### 删除 ![](https://i-blog.csdnimg.cn/direct/f0cf856157f54490baba368c1490af29.png) ### 持久化保存 ![](https://i-blog.csdnimg.cn/direct/cc8bdd4ece6d4769871318d03e2b8617.png) ### 判断key是否存在 ![](https://i-blog.csdnimg.cn/direct/36a5ac8ea05743459ada7488c8f5ce66.png) ### 清空当前库 ![](https://i-blog.csdnimg.cn/direct/776231495c9b40b98087740e465a5af3.png) ### 清空所有库 ![](https://i-blog.csdnimg.cn/direct/9ed1e021c1f04dd19056a7847fd68acd.png) ## 七、**Redis****主从复制** ### **环境配置** redis-node1 master redis-node2 slave redis-node3 slave ### **配置主从同步** #### **修改三个****节点的配置文件** ![](https://i-blog.csdnimg.cn/direct/1e9b512cfeb04addbc1c01c40351c2ad.png) #### **配置****slave****节点** ![](https://i-blog.csdnimg.cn/direct/5c65806b196e42e399599ceec494b43d.png) ![](https://i-blog.csdnimg.cn/direct/1a8633478e084439a11fdb8a5645ec59.png) 测试 ![](https://i-blog.csdnimg.cn/direct/0ed88eeee0324045aa08e53e70b754c0.png) master ![](https://i-blog.csdnimg.cn/direct/dbb33ea8f0bb4d199833cc1fd0190f6d.png) slave ![](https://i-blog.csdnimg.cn/direct/14cf9e0be7194afba7a125c01beded92.png) ## 八、Redis主从同步原理 Redis 的主从同步是一种数据复制机制,用于将主节点的数据同步到从节点,以实现数据的备份、高可用性和读写分离。 ### **建立主从关系** 1. 配置主从节点 * 在 Redis 中,可以通过配置文件或者命令行参数来指定主从关系。一般来说,将一个 Redis 实例配置为主节点,其他实例配置为从节点。 * 从节点在启动时会向主节点发送一个 `SYNC` 命令,请求进行数据同步。 ### **全量同步** 1. 生成 RDB 文件 * 当主节点接收到从节点的 `SYNC` 命令后,会执行 `BGSAVE` 命令,生成一个 RDB(Redis Database)文件,这是一个内存快照,包含了主节点当前的所有数据。 * 主节点在生成 RDB 文件的同时,会将新的写操作记录到一个缓冲区中。 2. 发送 RDB 文件和缓冲区内容 * 主节点生成 RDB 文件后,会将该文件发送给从节点。从节点接收到 RDB 文件后,会将其加载到内存中,恢复数据状态。 * 同时,主节点会将缓冲区中的写操作发送给从节点,从节点按照这些操作进行数据的同步更新。 ### **增量同步** 1. 记录写操作 * 在全量同步完成后,主节点和从节点的数据状态保持一致。此后,主节点每执行一次写操作,都会将该操作记录到一个复制积压缓冲区中。 2. 同步写操作 * 从节点会不断地向主节点发送 `REPLCONF ACK` 命令,报告自己的复制偏移量。主节点根据从节点的复制偏移量,判断从节点需要哪些写操作,并将这些操作发送给从节点进行同步。 ### **心跳机制** 1. 维持连接 * 为了保持主从节点之间的连接,从节点会定期向主节点发送 `PING` 命令,主节点收到后会回复 `PONG` 命令。 * 这个心跳机制可以检测主从节点之间的连接状态,及时发现并处理连接故障。 ### **故障转移** 1. 主节点故障 * 如果主节点出现故障,从节点可以通过选举机制,选出一个新的主节点。这个过程可以手动触发,也可以通过 Redis 的哨兵(Sentinel)机制自动完成。 * 当新的主节点选举出来后,其他从节点会重新与新的主节点建立主从关系,进行数据同步。 ![](https://i-blog.csdnimg.cn/direct/76e27bc7dcbc43feb986f3ca3707bc82.png) > slave 节点发送同步亲求到 master 节点 > slave 节点通过 master 节点的认证开始进行同步 > master 节点会开启 bgsave 进程发送内存 rbd 到 slave 节点,在此过程中是异步操作,也就是说 > master 节点仍然可以进行写入动作 > slave 节点收到 rdb 后首先清空自己的所有数据 > slave 节点加载 rdb 并进行数据恢复 > 在 master 和 slave 同步过程中 master 还会开启新的 bgsave 进程把没有同步的数据进行缓存 > 然后通过自有的 replactionfeedslave 函数把未通过内存快照发动到 slave 的数据一条一条写入到slave中 ## 九、**Redis****的哨兵(高可用)** Redis 的哨兵(Sentinel)是一种用于实现 Redis 高可用的机制。它主要负责监控 Redis 主从服务器的运行状态,并在主服务器出现故障时自动进行故障转移,将一个从服务器提升为主服务器,以保证 Redis 服务的持续可用性。 ### **哨兵的功能** 1. 监控 * 哨兵会持续监控 Redis 主从服务器的运行状态,包括主服务器是否在线、从服务器是否正常同步数据等。 * 哨兵通过向主从服务器发送 PING 命令来检测它们的状态。如果在一定时间内没有收到主服务器的响应,或者从服务器与主服务器的同步出现问题,哨兵会标记相应的服务器为下线状态。 2. 自动故障转移 * 当哨兵检测到主服务器不可用时,它会启动自动故障转移流程。 * 首先,哨兵会从所有的从服务器中选出一个最合适的服务器作为新的主服务器。选择的标准通常包括从服务器的数据完整性、与主服务器断开连接的时间等因素。 * 然后,哨兵会向其他从服务器发送命令,让它们重新配置为主服务器的从服务器,并开始从新的主服务器同步数据。 * 最后,哨兵会将新的主服务器信息通知给客户端,以便客户端可以重新连接到新的主服务器进行数据操作。 3. 配置提供者 * 哨兵可以作为 Redis 客户端的配置提供者,客户端可以向哨兵查询当前的主服务器地址,以便连接到正确的服务器进行数据操作。 * 当主服务器发生故障转移后,客户端可以通过向哨兵查询新的主服务器地址,自动切换到新的主服务器,无需手动修改配置。 ### **哨兵的工作原理** 1. 哨兵集群 * 为了提高可靠性,通常会部署多个哨兵实例组成一个哨兵集群。 * 哨兵集群中的每个实例都会独立地监控 Redis 主从服务器的状态,并通过相互通信来协调故障转移等操作。 * 当多个哨兵实例同时检测到主服务器不可用时,它们会通过投票机制来确定是否进行故障转移。只有当大多数哨兵实例都认为主服务器不可用时,才会启动故障转移流程。 2. 主观下线和客观下线 * 当一个哨兵实例检测到主服务器不可用时,它会将主服务器标记为主观下线状态。 * 如果多个哨兵实例都检测到主服务器不可用,并且达到一定数量的哨兵实例都认为主服务器不可用,那么主服务器会被标记为客观下线状态。 * 只有当主服务器被标记为客观下线状态时,哨兵才会启动故障转移流程。 3. 领导者选举 * 在进行故障转移时,哨兵集群需要选举出一个领导者来执行具体的故障转移操作。 * 领导者选举是通过投票机制来实现的。每个哨兵实例都会向其他实例发送自己的投票信息,包括自己的 ID 和推荐的领导者 ID。 * 最终,获得大多数选票的哨兵实例会成为领导者,负责执行故障转移操作。 ### 哨兵中的三个定时任务 在 Redis 哨兵(Sentinel)中,有三个重要的定时任务,它们对于实现高可用起着关键作用。 **定时任务一:每个 Sentinel 节点对主从节点和其他 Sentinel 节点发送 PING 命令** 1. 目的 * 监控主从节点以及其他 Sentinel 节点的状态。通过定期发送 PING 命令,可以及时发现节点是否在线、是否正常响应。 * 对于主从节点,判断其是否正常运行,是否出现故障。对于其他 Sentinel 节点,确保 Sentinel 集群的连通性和一致性。 2. 执行频率 * 一般情况下,每隔 1 秒向主从节点和其他 Sentinel 节点发送 PING 命令。 3. 作用 * 及时发现节点故障:如果某个节点在一定时间内没有响应 PING 命令,Sentinel 会将其标记为疑似下线状态。如果多个 Sentinel 都认为该节点疑似下线,那么该节点会被标记为客观下线状态,触发故障转移流程。 * 保持 Sentinel 集群的信息同步:通过互相发送 PING 命令,Sentinel 节点可以了解其他节点的状态和配置信息,确保整个集群的一致性。 **定时任务二:每个 Sentinel 节点通过命令连接向主从节点发送 INFO 命令** 1. 目的 * 获取主从节点的详细信息,包括主节点的运行 ID、复制状态、从节点列表等。 * 通过 INFO 命令获取的信息可以帮助 Sentinel 更好地了解主从架构的状态,以便在需要进行故障转移时做出更准确的决策。 2. 执行频率 * 每隔 10 秒向主从节点发送 INFO 命令。 3. 作用 * 监控主从复制状态:可以了解从节点与主节点的同步进度、连接状态等。如果发现从节点同步出现问题,可以及时采取措施,如重新配置从节点或进行故障转移。 * 发现新的从节点:如果主节点添加了新的从节点,Sentinel 可以通过 INFO 命令及时发现,并将其纳入监控范围。 * 更新主节点信息:主节点的运行状态可能会发生变化,如内存使用情况、客户端连接数等。通过 INFO 命令可以及时获取这些信息,以便 Sentinel 做出相应的调整。 **定时任务三:每个 Sentinel 节点向其他 Sentinel 节点发送 PUBLISH 命令,向频道_sentinel_:hello 发布自身信息及主从状态** 1. 目的 * Sentinel 节点之间通过发布和订阅这个频道来进行信息交流和协调。每个 Sentinel 节点会将自己的信息以及所监控的主从节点的状态发布到这个频道,其他 Sentinel 节点可以通过订阅该频道来获取这些信息。 * 这样可以实现 Sentinel 集群的自动发现和信息共享,提高整个集群的可靠性和稳定性。 2. 执行频率 * 每隔 2 秒向频道_sentinel_:hello 发布自身信息及主从状态。 3. 作用 * 自动发现 Sentinel 节点:新加入的 Sentinel 节点可以通过订阅这个频道来快速了解集群中的其他节点,实现自动发现和加入集群。 * 信息共享:每个 Sentinel 节点可以了解其他节点对主从节点的判断和状态,以便在进行故障转移等操作时进行协商和决策。例如,在确定主节点是否下线以及选择新的主节点时,多个 Sentinel 节点可以通过这个频道进行信息交流,达成一致。 ### **哨兵的实验过程** 在所有阶段中关闭 protected-mode no 在 master 节点中 编辑配置文件 ![](https://i-blog.csdnimg.cn/direct/c3809ef48dc94fe98a0680e2a60d30c8.png) ![](https://i-blog.csdnimg.cn/direct/a0168d04defb4bc0bb829650c559cb9c.png) ![](https://i-blog.csdnimg.cn/direct/31d5bff9be4f4b369a0c1934b98f62c0.png) ![](https://i-blog.csdnimg.cn/direct/71dd96ee267842bd81e6aa19743bc043.png) ![](https://i-blog.csdnimg.cn/direct/3d0670cc869f475583ef16a6e7681be9.png) > protected-mode no #关闭保护模式 > > port 26379 #监听端口 > > daemonize no #进入不打如后台 > > pidfile /var/run/redis-sentinel.pid #sentinel进程pid文件 > > loglevel notice #日志级别 > > sentinel monitor mymaster 172.25.254.128 6379 2 #创建sentinel监控监控master主机,2表示必须得到2票 > > sentinel down-after-milliseconds mymaster 10000 #master中断时长,10秒连不上视为 master下线 > > sentinel parallel-syncs mymaster 1 #发生故障转移后,同时开始同步新master数据的slave数量 > > sentinel failover-timeout mymaster 180000 #整个故障切换的超时时间为3分钟 复制配置文件到其他阶段 ![](https://i-blog.csdnimg.cn/direct/a4ff68ffe0b34fde839d8a5eddac5ddb.png) 将哨兵的配置文件进行备份 \[root@redis-node1 redis\]# cp sentinel.conf sentinel.conf.bak 启动服务 ![](https://i-blog.csdnimg.cn/direct/2c3e17e2f0f04f4eaac76181367f052c.png) 测试 在开一个 master 节点终端 ![](https://i-blog.csdnimg.cn/direct/23386bc88d324fa19f28835561fa84cf.png) ![](https://i-blog.csdnimg.cn/direct/6356f2b1b53a409a8fa7850c70946dd1.png) 172.25.254.20成为了新的master ![](https://i-blog.csdnimg.cn/direct/c7a108bf552a445fb7d565ea37da8678.png) ## **十、Redis哨兵模式会存在的问题及解决方案** 问题: 在生产环境中如果 master 和 slave 中的网络出现故障,由于哨兵的存在会把 master 提出去 当网络恢复后, master 发现环境发生改变, master 就会把自己的身份转换成 slave master 变成 slave 后会把网络故障那段时间写入自己中的数据清掉,这样数据就丢失了。 解决: master 在被写入数据时会持续连接 slave , mater 确保有 2 个 slave 可以写入我才允许写入 如果 slave 数量少于 2 个便拒绝写入 临时更改 ![](https://i-blog.csdnimg.cn/direct/bb6e22d1cc0640e3b0219b62f2454668.png) 如果要永久保存写到配置文件中 /etc/redis/6379.conf \[root@redis-node3 redis\]# vim /etc/redis/6379.conf ![](https://i-blog.csdnimg.cn/direct/1741df6d025f4d6cb1f4427639503046.png) ## 十一、Redis cluster集群 Redis Cluster 是 Redis 的分布式解决方案,它可以将数据自动分布到多个节点上,实现数据的分布式存储和高可用。以下是关于 Redis Cluster 的详细介绍: ### **架构特点** 1. #### 去中心化 * Redis Cluster 没有中心节点,每个节点都是平等的,都可以处理客户端的请求。这种去中心化的架构使得系统更加健壮,不会因为中心节点的故障而导致整个系统瘫痪。 2. #### 数据分片 * Redis Cluster 将数据分成 16384 个哈希槽(hash slot),每个节点负责一部分哈希槽。当客户端向 Redis Cluster 发送请求时,Redis Cluster 会根据请求的 key 计算出对应的哈希槽,然后将请求转发到负责该哈希槽的节点上。 3. #### 高可用 * Redis Cluster 支持主从复制,每个主节点都有一个或多个从节点。当主节点出现故障时,从节点会自动升级为主节点,继续提供服务。此外,Redis Cluster 还支持自动故障转移,当一个节点出现故障时,其他节点会自动重新分配哈希槽,保证系统的可用性。 ### **节点通信** 1. #### Gossip 协议 * Redis Cluster 中的节点通过 Gossip 协议进行通信。Gossip 协议是一种去中心化的通信协议,它可以让节点之间快速地交换信息。在 Redis Cluster 中,节点通过 Gossip 协议交换节点状态、哈希槽信息、主从关系等信息。 2. #### 消息类型 * Redis Cluster 中的节点通过发送不同类型的消息来进行通信。常见的消息类型有 PING、PONG、MEET、FAIL 等。PING 和 PONG 消息用于节点之间的心跳检测,MEET 消息用于新节点加入集群,FAIL 消息用于通知其他节点某个节点出现故障。 ### **客户端连接** 1. #### 客户端路由 * Redis Cluster 的客户端需要实现路由功能,即根据请求的 key 计算出对应的哈希槽,然后将请求转发到负责该哈希槽的节点上。客户端可以通过多种方式实现路由功能,例如使用 Redis Cluster 的官方客户端、使用代理服务器等。 2. #### 连接重定向 * 当客户端连接到一个错误的节点时,该节点会返回 MOVED 或 ASK 错误,告诉客户端应该连接到哪个节点上。客户端收到这些错误后,会重新连接到正确的节点上。 ### **数据迁移** 1. #### 手动迁移 * Redis Cluster 支持手动数据迁移,管理员可以使用 Redis Cluster 的命令将数据从一个节点迁移到另一个节点上。手动数据迁移通常用于节点扩容、缩容等场景。 2. #### 自动迁移 * Redis Cluster 也支持自动数据迁移,当节点出现故障或者负载过高时,Redis Cluster 会自动将该节点上的哈希槽迁移到其他节点上。自动数据迁移可以保证系统的可用性和性能。 ### **创建R****edis cluster****的前提** 1. 每个 redis node 节点采用相同的硬件配置、相同的密码、相同的 redis 版本。 2. 每个节点必须开启的参数 cluster-enabled yes # 必须开启集群状态,开启后 redis 进程会有 cluster 显示 cluster-config-file nodes-6380.conf # 此文件有 redis cluster 集群自动创建和维护,不需要任何手 动操作 3. 所有 redis 服务器必须没有任何数据 4. 先启动为单机 redis 且没有任何 key value ### **部署****redis cluster** 在所有redis主机中 \[root@redis-node1 \~\]# vim /etc/redis/redis.conf ![](https://i-blog.csdnimg.cn/direct/e20aa1acddae49178cd3535d2e18729b.png) ![](https://i-blog.csdnimg.cn/direct/ffdbfc4cdf0a4cee9b7dfb5dce4cffe8.png) ![](https://i-blog.csdnimg.cn/direct/8b1e70bb57e649b7a40515906a0e8840.png) ![](https://i-blog.csdnimg.cn/direct/0ff99322cb5e4e81a2f76c544e7b2e7a.png) > masterauth "123456" #集群主从认证 > requirepass "123456" #redis登陆密码 redis-cli 命令连接redis后要 > 用"auth 密码"进行认证 > cluster-enabled yes #开启cluster集群功能 > cluster-config-file nodes-6379.conf #指定集群配置文件 > cluster-node-timeout 15000 #节点加入集群的超时时间单位是ms \[root@redis-node1 \~\]# systemctl restart redis ![](https://i-blog.csdnimg.cn/direct/f274a5c486d0426586a40d686aae7a71.png) ![](https://i-blog.csdnimg.cn/direct/c4a8f5da58054068bf74525eae49d7d6.png) #### **redis-cli --cluster****参数说明** > \[root@redis-node1 \~\]# redis-cli --cluster help > Cluster Manager Commands: > create host1:port1 ... hostN:portN #创建集群 > --cluster-replicas \ #指定master的副本数 > check \ or \ \ #检测集群信息 > info \ or \ \ #查看集群信息 > fix \ or \ \ #修复集群 > reshard \ or \ \ #在线热迁移集群指定主机的slots数据 > rebalance \ or \ \ #平衡各集群主机的slot数量 > add-node new_host:new_port existing_host:existing_port #添加主机 > del-node host:port node_id #删除主机 > import host:port #导入外部redis服务器的数据到 > 当前集群 #### **创建****redis-cluster** > \[root@redis-node1 \~\]# redis-cli --cluster create -a 123456 \\ > \> 172.25.254.128:6379 172.25.254.10:6379 172.25.254.20:6379 \\ > \> 172.25.254.30:6379 172.25.254.40:6379 172.25.254.50:6379 \\ > \> --cluster-replicas 1 > Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. > \>\>\> Performing hash slots allocation on 6 nodes... > Master\[0\] -\> Slots 0 - 5460 #哈希槽分配 > Master\[1\] -\> Slots 5461 - 10922 > Master\[2\] -\> Slots 10923 - 16383 > Adding replica 172.25.254.40:6379 to 172.25.254.128:6379 #主从分配情况 > Adding replica 172.25.254.50:6379 to 172.25.254.10:6379 > Adding replica 172.25.254.30:6379 to 172.25.254.20:6379 > M: 840e6a8999f3d94d5cdc38810aeb13e74c2087c3 172.25.254.128:6379 > slots:\[0-5460\] (5461 slots) master > M: 6b6df47989486b1a080b4debf1252b262a75bc42 172.25.254.10:6379 > slots:\[5461-10922\] (5462 slots) master > M: 2152850d03d2809ac172187e26f66460e57f6bf3 172.25.254.20:6379 > slots:\[10923-16383\] (5461 slots) master > S: 6870a0c91f0fcd0b94c032efe23e2622fe131919 172.25.254.30:6379 > replicates 2152850d03d2809ac172187e26f66460e57f6bf3 > S: 8df3eb9fca5d36aa420f83dd49614b2f3ed3f73a 172.25.254.40:6379 > replicates 840e6a8999f3d94d5cdc38810aeb13e74c2087c3 > S: 36c26c0faa74c117e3999a4c29a09868fc6ac2ee 172.25.254.50:6379 > replicates 6b6df47989486b1a080b4debf1252b262a75bc42 > Can I set the above configuration? (type 'yes' to accept): yes > \>\>\> Nodes configuration updated > \>\>\> Assign a different config epoch to each node > \>\>\> Sending CLUSTER MEET messages to join the cluster > Waiting for the cluster to join > . > \>\>\> Performing Cluster Check (using node 172.25.254.128:6379) > M: 840e6a8999f3d94d5cdc38810aeb13e74c2087c3 172.25.254.128:6379 > slots:\[0-5460\] (5461 slots) master > 1 additional replica(s) > S: 6870a0c91f0fcd0b94c032efe23e2622fe131919 172.25.254.30:6379 > slots: (0 slots) slave > replicates 2152850d03d2809ac172187e26f66460e57f6bf3 > M: 6b6df47989486b1a080b4debf1252b262a75bc42 172.25.254.10:6379 > slots:\[5461-10922\] (5462 slots) master > 1 additional replica(s) > S: 36c26c0faa74c117e3999a4c29a09868fc6ac2ee 172.25.254.50:6379 > slots: (0 slots) slave > replicates 6b6df47989486b1a080b4debf1252b262a75bc42 > M: 2152850d03d2809ac172187e26f66460e57f6bf3 172.25.254.20:6379 > slots:\[10923-16383\] (5461 slots) master > 1 additional replica(s) > S: 8df3eb9fca5d36aa420f83dd49614b2f3ed3f73a 172.25.254.40:6379 > slots: (0 slots) slave > replicates 840e6a8999f3d94d5cdc38810aeb13e74c2087c3 > \[OK\] All nodes agree about slots configuration. > \>\>\> Check for open slots... #检查打开的哈希槽位 > \>\>\> Check slots coverage... #检查槽位覆盖范围 > \[OK\] All 16384 slots covered. #所有槽位分配完成 ![](https://i-blog.csdnimg.cn/direct/25d624c32bb0427bbb96fdd75b4491df.png) ![](https://i-blog.csdnimg.cn/direct/0bcaa3acb9e74bccaaa663dda88f87a0.png) 现在的主从关系 > master:172.25.254.128 slave:172.25.254.40 > > master:172.25.254.10 slave:172.25.254.50 > > master:172.25.254.20 slave:172.25.254.30 #### **检测****redis****集群状态** ![](https://i-blog.csdnimg.cn/direct/adfabcb6972743a387825d7b1f70ca19.png) ![](https://i-blog.csdnimg.cn/direct/9ebdc8c3a9fb4e86a13f843d583debc0.png) #### **写入数据** ![](https://i-blog.csdnimg.cn/direct/923a9e911c89457bad8f183918507f03.png) ![](https://i-blog.csdnimg.cn/direct/f3f0f2a081ae4730884239b94a00b85f.png) #### **集群扩容** ##### 添加master ![](https://i-blog.csdnimg.cn/direct/35c8ed84847b4bcc9213a2b8ea28b19a.png) ![](https://i-blog.csdnimg.cn/direct/77e0520a065a4d7698d07bc96fd043f4.png) ##### 分配槽位 ![](https://i-blog.csdnimg.cn/direct/692bbaeda97847fd8438822babc2866e.png) ##### 添加salve ![](https://i-blog.csdnimg.cn/direct/d7d0dcf916dd4e79bd1904e2e1c73fb8.png) ![](https://i-blog.csdnimg.cn/direct/1e088e49667d45258a08e2d4193ce7b9.png) #### **clsuter****集群维护** 添加节点的时候是先添加 node 节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反,是先将被删除的Redis node 上的槽位迁移到集群中的其他 Redis node 节点上,然后再将其删除,如果一个Redis node 节点上的槽位没有被完全迁移,删除该 node 的时候会提示有数据且无法删除。 ![](https://i-blog.csdnimg.cn/direct/4dcc793308954cb99b091bf7ad1a10d8.png) ![](https://i-blog.csdnimg.cn/direct/1b61aadc5b4e42ea8b5081bc7e5548fd.png) ![](https://i-blog.csdnimg.cn/direct/88ba756e5f5148878ec422474a8d9ea9.png) 删除master ![](https://i-blog.csdnimg.cn/direct/b3e9d5ebe9be4dd89c130023138e97f1.png)

相关推荐
UFIT1 小时前
nginx性能优化与深度监控
运维·nginx
新辞旧梦3 小时前
企业微信自建消息推送应用
服务器·python·企业微信
虎头金猫3 小时前
如何解决 403 错误:请求被拒绝,无法连接到服务器
运维·服务器·python·ubuntu·chatgpt·centos·bug
gadiaola3 小时前
MySQL从入门到精通(三):MySQL数据类型、SQL语言—DDL
数据库·sql·mysql·database
muxue1784 小时前
关于almalinux分区配置:
linux·运维·数据库
海天胜景5 小时前
Asp.Net Core IIS发布后PUT、DELETE请求错误405
数据库·后端·asp.net
凯子坚持 c5 小时前
【金仓数据库征文】金仓数据库 KES:MySQL 迁移实用指南
数据库·金仓数据库 2025 征文·数据库平替用金仓
小刘|6 小时前
Redis 中简单动态字符串(SDS)的深入解析
数据库·redis·bootstrap
独行soc6 小时前
2025年渗透测试面试题总结-某服面试经验分享(附回答)(题目+回答)
linux·运维·服务器·网络安全·面试·职场和发展·渗透测试
C-20027 小时前
使用Deployment部署运行Nginx和Apache服务
运维·kubernetes·apache