分布式文件存储与数据缓存 Redis高可用分布式实践(下)(三)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式文件存储与数据缓存 Redis高可用分布式实践(下)(三)

十、Redis事务

10.1 事务概念与ACID特性

数据库层面事务

在数据库层面,事务是指一组操作,这些操作要么全都被成功执行,要么全都不执行。

数据库事务的四大特性

  • A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;
  • C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;
  • I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;
  • D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

Redis事务

Redis事务是一组命令的集合,一个事务中的所有命令都将被序列化,按照一次性、顺序性、排他性的执行一系列的命令。

Redis事务三大特性

  1. 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断;
  2. 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”。
  3. 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚;

Redis事务执行的三个阶段

  • 开启:以MULTI开始一个事务;
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面;
  • 执行:由EXEC命令触发事务;

10.2 事务的基本操作

Multi、Exec、discard

事务从输入Multi命令开始,输入的命令都会依次压入命令缓冲队列中,并不会执行,直到输入Exec后,Redis会将之前的命令缓冲队列中的命令依次执行。组队过程中,可以通过discard来放弃组队。

  • 正常执行
127.0.0.1:6379> MULTI            #开启事务
OK
127.0.0.1:6379(TX)> set id 2
QUEUED
127.0.0.1:6379(TX)> get id
QUEUED
127.0.0.1:6379(TX)> incr id
QUEUED
127.0.0.1:6379(TX)> incr id
QUEUED
127.0.0.1:6379(TX)> exec        #提交事务
1) OK
2) "2"
3) (integer) 3
4) (integer) 4
  • 放弃事务
127.0.0.1:6379> MULTI       #开启事务
OK
127.0.0.1:6379(TX)> get id
QUEUED
127.0.0.1:6379(TX)> incr id
QUEUED
127.0.0.1:6379(TX)> DISCARD       #放弃事务
OK
127.0.0.1:6379> get id
"4"
127.0.0.1:6379>
  • 全体连坐
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set name zj
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> incr t1
QUEUED
127.0.0.1:6379(TX)> get t1
QUEUED
127.0.0.1:6379(TX)> set email
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.

注意:

命令集合中含有错误的指令(注意是语法错误),均连坐,全部失败。一人犯罪全家遭殃。

  • 冤有头,债有主
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set age 11
QUEUED
127.0.0.1:6379(TX)> incr t1
QUEUED
127.0.0.1:6379(TX)> set email abc@163.com
QUEUED
127.0.0.1:6379(TX)> incr email      #语法正确,但是执行的时候会错误,该命令不会被执行。
QUEUED
127.0.0.1:6379(TX)> get age
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (integer) 5
3) OK
4) (error) ERR value is not an integer or out of range
5) "11"

注意:

运行时错误,即非语法错误,正确命令都会执行,错误命令返回错误。

十一、Redis集群

11.1 主从复制概念

概述

在现有企业中80%公司大部分使用的是redis单机服务,在实际的场景当中单一节点的redis容易面临风险。

面临问题:

  1. 机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的。
  2. 容量瓶颈。redis的数据保存在内存中,当我们有需求需要扩容 Redis 内存时,从 16G 的内存升到 64G,单机肯定是满足不了。当然,你可以重新买个 128G 内存的新机器。

解决办法

要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。

注意:

Redis 为了解决这个单一节点的问题,也会把数据复制多个副本部署到其他节点上进行复制,实现 Redis的高可用,实现对数据的冗余备份从而保证数据和服务的高可用。

什么是主从复制

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。

主从复制的作用

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  4. 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

11.2 主从复制搭建

通过不同的端口,来模拟不同的redis服务。但是在实际的开发中肯定不是这样搭建的主从集群。企业中一台服务器搭建一个redis

新建redis6379.conf配置文件

在新建配置文件之前先将redis服务停掉。

[root@localhost ~]# lsof -i:6379
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 1855 root    6u  IPv4  33744      0t0  TCP *:6379 (LISTEN)
redis-ser 1855 root    7u  IPv6  33745      0t0  TCP localhost:6379 (LISTEN)
[root@localhost ~]# kill 1855

在redis根目录下编写配置文件

include /usr/local/redis-6.2.6/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

新建redis6380.conf配置文件

include /usr/local/redis-6.2.6/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb

新建redis6381.conf配置文件

include /usr/local/redis-6.2.6/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb

启动三台redis服务器

./redis-server ../redis6379.conf
./redis-server ../redis6380.conf
./redis-server ../redis6381.conf

查看系统进程

打开三个窗口连接不同端口下的redis服务

./redis-cli -p 6379
./redis-cli -p 6380
./redis-cli -p 6381

查看服务详情

127.0.0.1:6379> info replication
127.0.0.1:6380> info replication
127.0.0.1:6381> info replication

在从库中指定主库

slaveof  <ip> <port>
127.0.0.1:6380> slaveof  127.0.0.1 6379
127.0.0.1:6381> slaveof 127.0.01 6379

主机写数据

127.0.0.1:6379> set test1 testvalue
OK

从机读数据

127.0.0.1:6380> get test1
"testvalue"
127.0.0.1:6381> get test1
"testvalue"

注意,从节点只能读数据不能写数据。

11.3 主从复制原理刨析

主从复制可以分为3个阶段

  • 连接建立阶段(即准备阶段)
  • 数据同步阶段
  • 命令传播阶段

复制过程大致分为6个过程

1、保存主节点(master)信息。

执行 slaveof 后 查看状态信息

info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up

2、从节点(slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该主节点建立网络连接

3、从节点与主节点建立网络连接

从节点会建立一个 socket 套接字,从节点建立了一个端口为51234的套接字,专门用于接受主节点发送的复制命令。

4、从节点发送ping命令到主节点

作用:

  • 检测主从之间网络套接字是否可用。
  • 检测主节点当前是否可以接受命令 。

5、权限认证

如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程

6、同步数据集

主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。

主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

例如:

保存一个缓存

set name zj

记录命令为

$3 \r \n
set \r \n
$4 \r \n
name \r \n
$5  \r \n
baizhan \r \n
偏移量 1000 1001 1002 1003 1004 1005 1006 1007 1008
字节值 $ 3 \r \n $ 4 n a m

7、命令持续复制。

当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。

11.4 哨兵监控概述

Redis主从复制缺点

当主机 Master 宕机以后,我们需要人工解决切换。

暴漏问题:

一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选取主节点,手动设置主从关系。

主从切换技术

当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式

哨兵模式概述

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

哨兵作用

  • 集群监控:负责监控redis master和slave进程是否正常工作
  • 消息通知:如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
  • 故障转移:如果master node挂掉了,会自动转移到slave node上
  • 配置中心:如果故障转移发生了,通知client客户端新的master地址

11.5 配置哨兵监控

新建sentinel-26379.conf配置文件

#端口
port 26380
#守护进程后台运行
daemonize yes
#日志文件
logfile "26380.log"
#主节点
sentinel monitor mymaster 192.168.66.100 6379 2

参数:

sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

新建sentinel-26380.conf文件

#端口
port 26380
#守护进程运行
daemonize yes
#日志文件
logfile "26380.log"
sentinel monitor mymaster 192.168.66.100 6379 2

新建sentinel-26381.conf文件

#端口
port 26381
#守护进程运行
daemonize yes
#日志文件
logfile "26381.log"
sentinel monitor mymaster 192.168.66.100 6379 2

实际开发中一个redis中搭配一个哨兵。

哨兵节点的启动

[root@localhost src]# ./redis-sentinel ../ sentinel-26379.conf
[root@localhost src]# ./redis-sentinel ../ sentinel-26380.conf
[root@localhost src]# ./redis-sentinel ../ sentinel-26381.conf

查看哨兵节点状态

[root@localhost src]# ./redis-cli -p 26379
127.0.0.1:26379> 
127.0.0.1:26379> 
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.66.100:6379,slaves=2,sentinels=3

11.6 哨兵监控原理刨析

监控阶段

过程:

  • sentinel(哨兵1)----->向master(主)和slave(从)发起info,拿到全信息。
  • sentinel(哨兵2)----->向master(主)发起info,就知道已经存在的sentinel(哨兵1)的信息,并且连接slave(从)。
  • sentinel(哨兵2)----->向sentinel(哨兵1)发起subscribe(订阅)。

通知阶段

sentinel不断的向master和slave发起通知,收集信息。

故障转移阶段

通知阶段sentinel发送的通知没得到master的回应,就会把master标记为SRI_S_DOWN,并且把master的状态发给各个sentinel,其他sentinel听到master挂了,说我不信,我也去看看,并把结果共享给各个sentinel,当有一半的sentinel都认为master挂了的时候,就会把master标记为SRI_0_DOWN。

问题来了:

这时就要把master给换掉了,到底谁当Master呢。

投票方式

方式:

自己最先接到哪个sentinel的竞选通知就会把票投给它。

剔除一些情况:

  1. 不在线的
  2. 响应慢的
  3. 与原来master断开时间久的
  4. 优先级原则


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8天前
|
数据采集 人工智能 分布式计算
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
阿里云推出的MaxFrame是链接大数据与AI的分布式Python计算框架,提供类似Pandas的操作接口和分布式处理能力。本文从部署、功能验证到实际场景全面评测MaxFrame,涵盖分布式Pandas操作、大语言模型数据预处理及企业级应用。结果显示,MaxFrame在处理大规模数据时性能显著提升,代码兼容性强,适合从数据清洗到训练数据生成的全链路场景...
25 5
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
|
7天前
|
存储 负载均衡 NoSQL
搭建高可用及负载均衡的Redis
通过本文介绍的高可用及负载均衡Redis架构,可以有效提升Redis服务的可靠性和性能。主从复制、哨兵模式、Redis集群以及负载均衡技术的结合,使得Redis系统在应对高并发和数据一致性方面表现出色。这些配置和技术不仅适用于小型应用,也能够支持大规模企业级应用的需求。希望本文能够为您的Redis部署提供实用指导和参考。
43 9
|
11天前
|
存储 固态存储 文件存储
并行文件存储在大模型训练中的探索与实践
阿里云智能集团存储产品专家何邦剑分享了并行文件存储CPFS在大模型训练中的应用。CPFS针对大模型训练的IO特点,优化性能、降低成本、提升用户体验。它支持多计算平台共享访问,具备数据分层存储、生命周期管理、缓存加速等特性,实现高效的数据处理与管理,显著提升训练效率和资源利用率。尤其在大规模集群中,CPFS提供了高吞吐、低延迟及灵活扩展的能力,助力客户如零一万物实现高性能训练。
|
18天前
|
缓存 NoSQL Redis
Redis经典问题:数据并发竞争
数据并发竞争是大流量系统(如火车票系统、微博平台)中常见的问题,可能导致用户体验下降甚至系统崩溃。本文介绍了两种解决方案:1) 加写回操作加互斥锁,查询失败快速返回默认值;2) 保持多个缓存备份,减少并发竞争概率。通过实践案例展示,成功提高了系统的稳定性和性能。
|
18天前
|
缓存 监控 NoSQL
Redis经典问题:数据不一致
在使用Redis时,缓存与数据库数据不一致会导致应用异常。主要原因包括缓存更新失败、Rehash异常等。解决方案有:重试机制、缩短缓存时间、优化写入策略、建立监控报警、定期验证一致性、采用缓存分层及数据回滚恢复机制。这些措施可确保数据最终一致性,提升应用稳定性和性能。
|
30天前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
阿里云容器服务ACK提供强大的产品能力,支持弹性、调度、可观测、成本治理和安全合规。针对拥有IDC或三方资源的企业,ACK One分布式云容器平台能够有效解决资源管理、多云多集群管理及边缘计算等挑战,实现云上云下统一管理,提升业务效率与稳定性。
|
1月前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
126 5
|
1月前
|
机器学习/深度学习 存储 运维
分布式机器学习系统:设计原理、优化策略与实践经验
本文详细探讨了分布式机器学习系统的发展现状与挑战,重点分析了数据并行、模型并行等核心训练范式,以及参数服务器、优化器等关键组件的设计与实现。文章还深入讨论了混合精度训练、梯度累积、ZeRO优化器等高级特性,旨在提供一套全面的技术解决方案,以应对超大规模模型训练中的计算、存储及通信挑战。
76 4
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
76 8
|
2月前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
64 16