惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
量子位
B
Blog RSS Feed
Schneier on Security
Schneier on Security
L
LINUX DO - 最新话题
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
N
News | PayPal Newsroom
阮一峰的网络日志
阮一峰的网络日志
Microsoft Security Blog
Microsoft Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tailwind CSS Blog
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
PCI Perspectives
PCI Perspectives
aimingoo的专栏
aimingoo的专栏
D
Docker
T
The Exploit Database - CXSecurity.com
Last Week in AI
Last Week in AI
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
月光博客
月光博客
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
J
Java Code Geeks
O
OpenAI News
C
Cisco Blogs
Hacker News - Newest:
Hacker News - Newest: "LLM"
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Help Net Security
Help Net Security
Scott Helme
Scott Helme
The Hacker News
The Hacker News
Y
Y Combinator Blog
A
Arctic Wolf
V
V2EX
P
Proofpoint News Feed
Simon Willison's Weblog
Simon Willison's Weblog
A
About on SuperTechFans
S
Securelist
G
Google Developers Blog
Cyberwarzone
Cyberwarzone
The GitHub Blog
The GitHub Blog

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
Redis--Redis分布式系统的原理与实操
NE_STOP · 2026-05-11 · via 博客园_首页

Redis分布式系统

Redis分布式系统(Redis集群)很好的解决不同Redis节点存放不同数据,并将用户请求方便地路由到不同Redis的问题。

数据分区算法

分布式数据库系统会根据不同的数据分区算法,将数据分散存储到不同的服务器节点上,每个节点管理整个数据集合的一个子集。

无标题

常见的数据分区规则有两大类:顺序分区和哈希分区。

顺序分区

顺序分区是将数据按照某种顺序平均分配到不同的节点。

比如:轮询分区算法、时间片轮转分区算法、数据块分区算法、业务主题分区算法等。

轮询分区算法

每产生一个数据就依次分配的不同的节点。

该算法适合数据量不确定的场景。

在数据量庞大的情况下,每个节点的数据很平均。

但生产者与节点间的连接要长时间保存。

时间片轮转分区算法

在一个固定长度的时间片内,数据会分配到一个节点,时间片结束,新的数据就分配到下一个节点。

该算法可能会出现节点数据不平均的情况(每个时间片内产生的数据量不同)。

但生产者与节点间的连接只需一个正在使用的就行,使用完毕后释放连接。

数据块分区算法

数据总量确定的情况下,根据各个节点的存储能力,将某块数据分配到一个节点。

业务主题分区算法

不同的业务主题,分配到不同节点。

哈希分区

哈希分区规则是充分利用数据的哈希值来完成分配,对数据哈希值的不同使用方式产生了不同的哈希分区算法。

常见的哈希分区算法如下:

节点取模哈希算法

该算法的前提是,每个节点都分配好了一个唯一序号,对于N个节点的分布式系统,序号范围是【0,N-1】.

然后选取数据本身作为key,计算hash(key)与节点N的模。计算结果就是该数据存储的节点的序号。

该算法优点是简单;缺点是如果分布式系统要扩容或缩容,已存的数据需要根据新的节点数据N进行数据迁移,否则根据key无法找到原来的数据。

实际上一般采用翻倍扩容方式,以减少扩容时数据迁移的比例。

一致性哈希分区算法

一致性哈希算法通过一致性hash环的数据结构实现。

环的起点是0,终点是232-1,并且起点和终点重合,环中间的整数按顺/逆时针分步。

无2标题

上图中o1、o2、o3、o4代表待分配的数据,红色方框是这4个数据的hash(o)在hash环中的落点。

m0、m1、m2代表三个节点,绿色圆圈表示三个节点的hash(m)在hash环中的落点。

数据的hash(o)按照顺/逆时针方向离哪个hash(m)最近,就存在哪个节点上。

该算法的优点是节点扩容或缩容时,只对最近的节点有影响,其他节点无影响。

缺点是:容易形成数据倾斜。且节点变化影响的数据量大,所以不适合数据节点少的场景。

虚拟槽分区算法

该算法首先虚拟出一个固定数量的整数集合,集合中的每个数称为一个slot槽。

槽的数据一般远大于节点数量,然后将槽瓶平均映射到各个节点上。

例如Redis 分布式系统中虚拟了16384个槽,范围是【0,16383】.假设有3个节点,那么solt槽和节点的映射关系如下:

无标3题

数据与槽有关系,和节点没关系。

数据通过hash(key)映射到槽:solt=hash(key)%soltNums。

该算法优点:解耦数据和节点,无需维护节点,只需维护与solt槽的关系。

Redis数据分区就是采用这个算法,计算公式为solt=CRC16%16384.

系统搭建

系统架构

一个master配一个slave。master和slave的关系在搭建成功后会自动分配。

无标4题

删除持久化文件

先将之前Redis主从集群在Redis安装目录下生成的RDB文件dump638*.conf和AOF持久化文件删除。

因为Redis分布式系统要求创建在一个空的数据库之上。

AOF持久化文件全部上appendonlydir目录中。

然后再Redis安装目录中mkdir一个新目录 cluster-dis。

将cluster 目录中的redis.conf 和redis6380.conf文件复制到cluster-dis 目录。

修改redis.conf

  1. dir

    指定工作目录为前面创建的cluster-dis目录。持久化文件、节点配置文件都在这个目录中生成。

    dir "/opt/apps/redis/cluster-dis"
    
  2. cluster-enabled

    cluster-enabled yes  # 开启集群模式
    
  3. cluster-config-file

    指定集群节点的配置文件,该文件会在每次节点启动时自动生成,其在dir属性指定的目录。

    该属性仍然保持注释,在后面的每个节点单独的配置文件中配置它。

  4. cluster-node-timeout

    cluster-node-timeout 15000 # 指定集群节点间通信的超时阈值,单位毫秒
    
  5. 修改redis6380.conf

无标5题

  1. 复制5个配置文件:redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、redis6385.conf

将端口号全部换为对应的端口号。

系统的启动与关闭

  1. 使用redis-server redis638*.conf 启动各个节点。此时在cluster-dis目录中生成了6个nodes的配置文件。

  2. 这些节点启动后仍然时6个独立的Redis,通过redis-cli --cluster create 命令将6个节点创建成一个分布式系统。

    redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
    

    当询问是,输入yes 即可创建完成。

无6标题

  1. 测试系统

    通过cluster nodes 命令可以查看各节点的关系及连接情况,只要看到每个节点的connected,说明系统搭建成功。对于命令redis-cli 需要注意:

    • redis-cli 带有参数-c 表示要连接的是一个集群,而不是一个节点
    • 端口号可以使用6个中的任意一个。

无标7题

  1. 关系系统:将各个节点shutdown 即可。

    redis-cli -p 5380 shutdown
    

集群操作

  1. 先连接集群

    redis-cli -c -p 6380
    
  2. 写入数据:单个key写入没有问题,一次写入多个key会报错。

    当批量写入多个key时,由于多个key会计算出多个solt。多个solt可能会对应多个节点,而一次只能写入一个节点,所有该操作会报错。

    不过,系统提供了批量写入多个key的方案,为这些key指定一个统一的group,让这个group 作为计算slot的唯一值。

    mset name{emp} ali age{emp} 22
    

无8标题

集群查询

  1. 查询key的slot:通过cluser keyslot 查询指定key的slot

    cluster keyslot emp # 查询emp的slot
    
  2. 查询slot中key的数量:通过cluster countkeyinslot 查询指定slot中包含key的个数

    cluster countkeyinslot 13178
    
  3. 查询slot中的key:通过cluster getkeysinslot 查询指定slot中包含的key

    cluster getkeysinslot 13178
    

故障转移

分布式系统中某个master如果宕机,那么对应的slave就会自动晋升为master,如果原master又重新启动,那么原master会自动变为新master的slave。

全覆盖需求

如果某slot范围对应的节点全部宕机,那么分布式系统是否还可以对外提供服务,取决于属性cluster-require-full-coverage的设置。

该属性的取值有:

  • yes:默认值,要求所有slot节点必须全覆盖的情况下系统才能运行。
  • no:slot节点不全的情况下系统也可以提供查询服务。

集群扩容

这里新增两个新节点:端口号为6386的master和端口号为6387的slave节点。

  1. 复制并修改两个配置文件。

    使用redis6380.conf 复制出redis6386.conf 、redis6387.conf ,并修改端口号。

  2. 启动这两个节点。

    在这里先启动分布式系统,执行下列命令

    ./start-redis-cluster.sh
    

    启动这两个新节点后,他们还是孤立节点,和其他节点没有任何关系。

  3. 添加master节点

    redis-cli -c --cluster add-node 127.0.0.1:6386 127.0.0.1:6380
    

    通过命令redis-cli -c --cluster add-node {newHost}:{newPort} {existHost}:{existPort}将新节点加入到系统中,其中{newHost}:{newPort} 是新节点的地址,{existHost}:{existPort} 是原系统中任意节点地址。

    添加完成后,此时新master还没有对应的slot。

  4. 分配slot。

    由于slot数量不变,所以slot分配本质就是一个slot的移动过程。

    通过redis-cli -c --cluster reshard {existHost}:{existPort}命令开启slot分配流程。{existHost}:{existPort} 为分布式系统中的任意节点地址。

无标9题

该流程会先查询当前节点的slot的分配情况。

然后开始Q&A交互。一共询问了四个问题,这里有三个:

  • 准备移动多少slot?

  • 谁来接收移动的slot

  • 选择要移动slot的源节点。这里有以下两种方案:

    1.选择键入all,表示所有已存在的slot的节点都作为源节点,将slot进行全局大分配。
    2.选择其他部分节点作为slot源节点。将源节点的动态ID复制到这里,每个ID键入完毕后回车,然后再键入下一个源节点ID,直到最后一个键入完毕后再键入done。
    

    这里键入的是all。进行全局大分配。

    其会先检测指定的slot源节点的数据,然后指定出reshard方案。

无标10题

 这里会再进行一次Q&A交互,询问是否继续处理推荐的方案。键入yes。开始真正的全局分配,直至完成。

 此时master节点新增完成。
  1. 添加slave节点。

    先启动这个节点。

    执行命令redis-cli -c --cluster add-node {newHost}:{newPort} {existHost}:{existPort} --cluster-slave --cluster-master-id masterID 将新节点指定为master的slave。

无11标题

此时通过redis-cli -c -p 6386 cluster nodes 命令看到其已添加成功。

集群缩容

这里将slave节点6387和master节点6386从系统中删除。

  1. 删除slave节点

    执行redis-cli --cluster del-node <delHost>:<dePort> delNodeId 命令删除。

  2. 移出master的slot

    在删除一个master之前,保证该master没有分配的slot。否则无法删除。

    执行redis-cli -c --cluster reshard 127.0.0.1:6380

    可以看到6386有1999个slot,所以键入1999,然后键入要接收的master节点的id,

    然后键入6386节点(源节点)的id,然后键入done,然后键入yes,此时slot移出完成。

无标12题

  1. 删除master节点

    执行redis-cli --cluster del-node <delHost>:<dePort> delNodeId 命令删除。

    此时删除完成。

分布式系统的限制

  • 仅支持0号数据库
  • 批量操作key有限制
  • 分区仅限于key
  • 事务支持有限
  • 不支持分级管理