mirror of https://github.com/dunwu/db-tutorial.git
64 lines
64 KiB
HTML
64 lines
64 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en-US">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Redis 集群 | DB-TUTORIAL</title>
|
||
<meta name="generator" content="VuePress 1.9.9">
|
||
<link rel="icon" href="/db-tutorial/img/favicon.ico">
|
||
<script src="https://cdn.wwads.cn/js/makemoney.js" type="text/javascript"></script>
|
||
<meta name="description" content="☕ db-tutorial 是一个数据库教程。">
|
||
<meta name="keywords" content="vuepress,theme,blog,vdoing">
|
||
<meta name="theme-color" content="#11a8cd">
|
||
<meta name="wwads-cn-verify" content="mxqWx62nfQQ9ocT4e5DzISHzOWyF4s">
|
||
|
||
<link rel="preload" href="/db-tutorial/assets/css/0.styles.51390d19.css" as="style"><link rel="preload" href="/db-tutorial/assets/js/app.be3f2e92.js" as="script"><link rel="preload" href="/db-tutorial/assets/js/2.aded268b.js" as="script"><link rel="preload" href="/db-tutorial/assets/js/50.ee6f08b7.js" as="script"><link rel="prefetch" href="/db-tutorial/assets/js/10.551ab278.js"><link rel="prefetch" href="/db-tutorial/assets/js/11.c049b6a2.js"><link rel="prefetch" href="/db-tutorial/assets/js/12.92d587d6.js"><link rel="prefetch" href="/db-tutorial/assets/js/13.a7b35fa5.js"><link rel="prefetch" href="/db-tutorial/assets/js/14.9ec959b5.js"><link rel="prefetch" href="/db-tutorial/assets/js/15.e7943372.js"><link rel="prefetch" href="/db-tutorial/assets/js/16.c6ad7b26.js"><link rel="prefetch" href="/db-tutorial/assets/js/17.39500ebd.js"><link rel="prefetch" href="/db-tutorial/assets/js/18.29949979.js"><link rel="prefetch" href="/db-tutorial/assets/js/19.78f879b8.js"><link rel="prefetch" href="/db-tutorial/assets/js/20.3ce14df7.js"><link rel="prefetch" href="/db-tutorial/assets/js/21.9d311c7c.js"><link rel="prefetch" href="/db-tutorial/assets/js/22.90234550.js"><link rel="prefetch" href="/db-tutorial/assets/js/23.12cf9e2d.js"><link rel="prefetch" href="/db-tutorial/assets/js/24.5b436e46.js"><link rel="prefetch" href="/db-tutorial/assets/js/25.8f2dc7d9.js"><link rel="prefetch" href="/db-tutorial/assets/js/26.61665ff4.js"><link rel="prefetch" href="/db-tutorial/assets/js/27.dfc7cc88.js"><link rel="prefetch" href="/db-tutorial/assets/js/28.a6286a66.js"><link rel="prefetch" href="/db-tutorial/assets/js/29.bfa8c106.js"><link rel="prefetch" href="/db-tutorial/assets/js/3.82108019.js"><link rel="prefetch" href="/db-tutorial/assets/js/30.c93b7a2e.js"><link rel="prefetch" href="/db-tutorial/assets/js/31.d48aab81.js"><link rel="prefetch" href="/db-tutorial/assets/js/32.33f8bb7c.js"><link rel="prefetch" href="/db-tutorial/assets/js/33.eb3b622d.js"><link rel="prefetch" href="/db-tutorial/assets/js/34.1ba1a06c.js"><link rel="prefetch" href="/db-tutorial/assets/js/35.24e4fee8.js"><link rel="prefetch" href="/db-tutorial/assets/js/36.dc61504e.js"><link rel="prefetch" href="/db-tutorial/assets/js/37.f1c9c729.js"><link rel="prefetch" href="/db-tutorial/assets/js/38.5024023f.js"><link rel="prefetch" href="/db-tutorial/assets/js/39.30ed016e.js"><link rel="prefetch" href="/db-tutorial/assets/js/4.884deeca.js"><link rel="prefetch" href="/db-tutorial/assets/js/40.6a6327f0.js"><link rel="prefetch" href="/db-tutorial/assets/js/41.3767f4d8.js"><link rel="prefetch" href="/db-tutorial/assets/js/42.14a20b0f.js"><link rel="prefetch" href="/db-tutorial/assets/js/43.b059081c.js"><link rel="prefetch" href="/db-tutorial/assets/js/44.73f724d9.js"><link rel="prefetch" href="/db-tutorial/assets/js/45.68f2ab27.js"><link rel="prefetch" href="/db-tutorial/assets/js/46.aed8a61f.js"><link rel="prefetch" href="/db-tutorial/assets/js/47.3bbf2366.js"><link rel="prefetch" href="/db-tutorial/assets/js/48.81688356.js"><link rel="prefetch" href="/db-tutorial/assets/js/49.1d366c93.js"><link rel="prefetch" href="/db-tutorial/assets/js/5.42f2cdb7.js"><link rel="prefetch" href="/db-tutorial/assets/js/51.47835d9d.js"><link rel="prefetch" href="/db-tutorial/assets/js/52.b0cab79c.js"><link rel="prefetch" href="/db-tutorial/assets/js/53.106440a2.js"><link rel="prefetch" href="/db-tutorial/assets/js/54.340ab690.js"><link rel="prefetch" href="/db-tutorial/assets/js/55.00623de9.js"><link rel="prefetch" href="/db-tutorial/assets/js/56.9f086601.js"><link rel="prefetch" href="/db-tutorial/assets/js/57.f5ad5f3f.js"><link rel="prefetch" href="/db-tutorial/assets/js/58.14827368.js"><link rel="prefetch" href="/db-tutorial/assets/js/59.c41f57d6.js"><link rel="prefetch" href="/db-tutorial/assets/js/6.5a5b4e54.js"><link rel="prefetch" href="/db-tutorial/assets/js/60.314534c0.js"><link rel="prefetch" href="/db-tutorial/assets/js/61.1ea5e4b7.js"><link rel="prefetch" href="/db-tutorial/assets/js/62.8b52e8fc.js"><link rel="prefetch" href="/db-tutorial/assets/js/63.d2fa8325.js"><link rel="prefetch" href="/db-tutorial/assets/js/64.ea2577e7.js"><link rel="prefetch" href="/db-tutorial/assets/js/65.563da2bb.js"><link rel="prefetch" href="/db-tutorial/assets/js/66.34eb51bd.js"><link rel="prefetch" href="/db-tutorial/assets/js/67.ab57f04f.js"><link rel="prefetch" href="/db-tutorial/assets/js/68.15b6f540.js"><link rel="prefetch" href="/db-tutorial/assets/js/69.54590de4.js"><link rel="prefetch" href="/db-tutorial/assets/js/7.913bec54.js"><link rel="prefetch" href="/db-tutorial/assets/js/70.40a2cea2.js"><link rel="prefetch" href="/db-tutorial/assets/js/71.3ce50922.js"><link rel="prefetch" href="/db-tutorial/assets/js/72.b9c022e9.js"><link rel="prefetch" href="/db-tutorial/assets/js/73.fba94661.js"><link rel="prefetch" href="/db-tutorial/assets/js/74.998d6c2f.js"><link rel="prefetch" href="/db-tutorial/assets/js/75.6efb68b0.js"><link rel="prefetch" href="/db-tutorial/assets/js/76.57273256.js"><link rel="prefetch" href="/db-tutorial/assets/js/77.3ddffb5b.js"><link rel="prefetch" href="/db-tutorial/assets/js/78.8fde3d74.js"><link rel="prefetch" href="/db-tutorial/assets/js/79.7a472c31.js"><link rel="prefetch" href="/db-tutorial/assets/js/8.103b4774.js"><link rel="prefetch" href="/db-tutorial/assets/js/80.4c55c65f.js"><link rel="prefetch" href="/db-tutorial/assets/js/81.cbdb67b8.js"><link rel="prefetch" href="/db-tutorial/assets/js/82.9c14d852.js"><link rel="prefetch" href="/db-tutorial/assets/js/83.a3d7d272.js"><link rel="prefetch" href="/db-tutorial/assets/js/84.6994dacc.js"><link rel="prefetch" href="/db-tutorial/assets/js/85.aca8d788.js"><link rel="prefetch" href="/db-tutorial/assets/js/86.00671865.js"><link rel="prefetch" href="/db-tutorial/assets/js/87.9076c4e8.js"><link rel="prefetch" href="/db-tutorial/assets/js/88.bbe68dab.js"><link rel="prefetch" href="/db-tutorial/assets/js/89.e2173071.js"><link rel="prefetch" href="/db-tutorial/assets/js/9.386bfe3a.js"><link rel="prefetch" href="/db-tutorial/assets/js/90.429162f2.js"><link rel="prefetch" href="/db-tutorial/assets/js/91.6ecc7c85.js"><link rel="prefetch" href="/db-tutorial/assets/js/92.efe42934.js"><link rel="prefetch" href="/db-tutorial/assets/js/93.69562766.js"><link rel="prefetch" href="/db-tutorial/assets/js/94.04aebfbc.js"><link rel="prefetch" href="/db-tutorial/assets/js/95.fe7cfce4.js"><link rel="prefetch" href="/db-tutorial/assets/js/96.674475d6.js"><link rel="prefetch" href="/db-tutorial/assets/js/97.8a7b73f2.js"><link rel="prefetch" href="/db-tutorial/assets/js/98.bf85add1.js">
|
||
<link rel="stylesheet" href="/db-tutorial/assets/css/0.styles.51390d19.css">
|
||
</head>
|
||
<body class="theme-mode-light">
|
||
<div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/db-tutorial/" class="home-link router-link-active"><img src="https://raw.githubusercontent.com/dunwu/images/master/common/dunwu-logo.png" alt="DB-TUTORIAL" class="logo"> <span class="site-name can-hide">DB-TUTORIAL</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/db-tutorial/12.数据库/01.数据库综合/" class="nav-link">数据库综合</a></div><div class="nav-item"><a href="/db-tutorial/12.数据库/02.数据库中间件/" class="nav-link">数据库中间件</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关系型数据库" class="dropdown-title"><a href="/db-tutorial/12.数据库/03.关系型数据库/" class="link-title">关系型数据库</a> <span class="title" style="display:none;">关系型数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/01.综合/" class="nav-link">综合</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/02.Mysql/" class="nav-link">Mysql</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/99.其他/" class="nav-link">其他</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档数据库" class="dropdown-title"><!----> <span class="title" style="display:;">文档数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/04.文档数据库/01.MongoDB/" class="nav-link">MongoDB</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="KV数据库" class="dropdown-title"><!----> <span class="title" style="display:;">KV数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/05.KV数据库/01.Redis/" class="nav-link">Redis</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="搜索引擎数据库" class="dropdown-title"><!----> <span class="title" style="display:;">搜索引擎数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/07.搜索引擎数据库/01.Elasticsearch/" class="nav-link">Elasticsearch</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/07.搜索引擎数据库/02.Elastic/" class="nav-link">Elastic技术栈</a></li></ul></div></div> <a href="https://github.com/dunwu/db-tutorial" target="_blank" rel="noopener noreferrer" class="repo-link">
|
||
GitHub
|
||
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><!----> <nav class="nav-links"><div class="nav-item"><a href="/db-tutorial/12.数据库/01.数据库综合/" class="nav-link">数据库综合</a></div><div class="nav-item"><a href="/db-tutorial/12.数据库/02.数据库中间件/" class="nav-link">数据库中间件</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关系型数据库" class="dropdown-title"><a href="/db-tutorial/12.数据库/03.关系型数据库/" class="link-title">关系型数据库</a> <span class="title" style="display:none;">关系型数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/01.综合/" class="nav-link">综合</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/02.Mysql/" class="nav-link">Mysql</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/03.关系型数据库/99.其他/" class="nav-link">其他</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档数据库" class="dropdown-title"><!----> <span class="title" style="display:;">文档数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/04.文档数据库/01.MongoDB/" class="nav-link">MongoDB</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="KV数据库" class="dropdown-title"><!----> <span class="title" style="display:;">KV数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/05.KV数据库/01.Redis/" class="nav-link">Redis</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="搜索引擎数据库" class="dropdown-title"><!----> <span class="title" style="display:;">搜索引擎数据库</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/07.搜索引擎数据库/01.Elasticsearch/" class="nav-link">Elasticsearch</a></li><li class="dropdown-item"><!----> <a href="/db-tutorial/12.数据库/07.搜索引擎数据库/02.Elastic/" class="nav-link">Elastic技术栈</a></li></ul></div></div> <a href="https://github.com/dunwu/db-tutorial" target="_blank" rel="noopener noreferrer" class="repo-link">
|
||
GitHub
|
||
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>数据库综合</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>数据库中间件</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>关系型数据库</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>文档数据库</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>KV数据库</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><section class="sidebar-group collapsable is-sub-group depth-1"><p class="sidebar-heading open"><span>Redis</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/db-tutorial/pages/451b73/" class="sidebar-link">Redis 面试总结</a></li><li><a href="/db-tutorial/pages/94e9d6/" class="sidebar-link">Redis 应用指南</a></li><li><a href="/db-tutorial/pages/ed757c/" class="sidebar-link">Redis 数据类型和应用</a></li><li><a href="/db-tutorial/pages/4de901/" class="sidebar-link">Redis 持久化</a></li><li><a href="/db-tutorial/pages/379cd8/" class="sidebar-link">Redis 复制</a></li><li><a href="/db-tutorial/pages/615afe/" class="sidebar-link">Redis 哨兵</a></li><li><a href="/db-tutorial/pages/77dfbe/" aria-current="page" class="active sidebar-link">Redis 集群</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_1-redis-cluster-分区" class="sidebar-link">1. Redis Cluster 分区</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_1-1-集群节点" class="sidebar-link">1.1. 集群节点</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_1-2-分配-hash-槽" class="sidebar-link">1.2. 分配 Hash 槽</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_1-3-寻址" class="sidebar-link">1.3. 寻址</a></li><li class="sidebar-sub-header level4"><a href="/db-tutorial/pages/77dfbe/#_1-3-1-计算键属于哪个槽" class="sidebar-link">1.3.1. 计算键属于哪个槽</a></li><li class="sidebar-sub-header level4"><a href="/db-tutorial/pages/77dfbe/#_1-3-2-moved-错误" class="sidebar-link">1.3.2. MOVED 错误</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_1-4-重新分区" class="sidebar-link">1.4. 重新分区</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_1-5-ask-错误" class="sidebar-link">1.5. ASK 错误</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_2-redis-cluster-故障转移" class="sidebar-link">2. Redis Cluster 故障转移</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_2-1-复制" class="sidebar-link">2.1. 复制</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_2-2-故障检测" class="sidebar-link">2.2. 故障检测</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_2-3-故障转移" class="sidebar-link">2.3. 故障转移</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_2-4-选举新的主节点" class="sidebar-link">2.4. 选举新的主节点</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_3-redis-cluster-通信" class="sidebar-link">3. Redis Cluster 通信</a></li><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_4-redis-cluster-应用" class="sidebar-link">4. Redis Cluster 应用</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_4-1-集群功能限制" class="sidebar-link">4.1. 集群功能限制</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_4-2-集群规模限制" class="sidebar-link">4.2. 集群规模限制</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_4-3-集群配置" class="sidebar-link">4.3. 集群配置</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_5-其他-redis-集群方案" class="sidebar-link">5. 其他 Redis 集群方案</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_5-1-客户端分区方案" class="sidebar-link">5.1. 客户端分区方案</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_5-2-代理分区方案" class="sidebar-link">5.2. 代理分区方案</a></li><li class="sidebar-sub-header level4"><a href="/db-tutorial/pages/77dfbe/#_5-2-1-twemproxy" class="sidebar-link">5.2.1. Twemproxy</a></li><li class="sidebar-sub-header level4"><a href="/db-tutorial/pages/77dfbe/#_5-2-2-codis" class="sidebar-link">5.2.2. Codis</a></li><li class="sidebar-sub-header level3"><a href="/db-tutorial/pages/77dfbe/#_5-3-查询路由方案" class="sidebar-link">5.3. 查询路由方案</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/db-tutorial/pages/77dfbe/#_6-参考资料" class="sidebar-link">6. 参考资料</a></li></ul></li><li><a href="/db-tutorial/pages/1fc9c4/" class="sidebar-link">Redis 实战</a></li><li><a href="/db-tutorial/pages/537098/" class="sidebar-link">Redis 运维</a></li></ul></section></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>列式数据库</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>搜索引擎数据库</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-06225672><div class="articleInfo" data-v-06225672><ul class="breadcrumbs" data-v-06225672><li data-v-06225672><a href="/db-tutorial/" title="首页" class="iconfont icon-home router-link-active" data-v-06225672></a></li> <li data-v-06225672><a href="/db-tutorial/categories/?category=%E6%95%B0%E6%8D%AE%E5%BA%93" title="分类" data-v-06225672>数据库</a></li><li data-v-06225672><a href="/db-tutorial/categories/?category=KV%E6%95%B0%E6%8D%AE%E5%BA%93" title="分类" data-v-06225672>KV数据库</a></li><li data-v-06225672><a href="/db-tutorial/categories/?category=Redis" title="分类" data-v-06225672>Redis</a></li></ul> <div class="info" data-v-06225672><div title="作者" class="author iconfont icon-touxiang" data-v-06225672><a href="https://github.com/dunwu" target="_blank" title="作者" class="beLink" data-v-06225672>dunwu</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-06225672><a href="javascript:;" data-v-06225672>2020-06-24</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABH1JREFUSA3tVl1oHFUUPmdmd2ltklqbpJDiNnXFmgbFktho7YMPNiJSSZM0+CAYSkUELVhM6YuwIPpgoOKDqOBDC0XE2CQoNtQXBUFTTcCi+Wlh1V2TQExsUzcltd3M9Tt3ZjZzZ2fT+OJTL8yeM+eee757fmeJbq//KQL8X3DUSFOcfr7cRsRtxNQMWueeVzOkaITIGqQHNg5y8+jNW9ldM7A6nTpAjuolUikAwq7CE3WcM2RRDz+XGVgN3FptU/aUSlvq9Pa3iZ1+sgAqJyyAFqkipd9dqiwHF3P65YycLWc/6sqGrvoEoIp6DOFaX5h6+dnfjkWprwqsPk0dUGq5vySwDImC10KxFHgGL1SWoc92O3eVht09qdXNH11I2SsTsJYqMWzihqGMi+A+Garf3BAuuLI5oGlULyNfyB/HYNujwktOfRrMr5t77NmevqaUopx0grnKAyvVpmwUDB4x6FPXuGvYLTDwWsejwgtgkYKPqRJg8SV6xaiZ3ZTppGneS4yfH5/66fZSDHv+QZci/+h5c5UHtpy67JUqGppM0sh0Nc1dW6/N1W5Yoqat8/TU/VnadmdeW2PLLSyh0cvxBs3KbqTmwYPpxN4do/mzE8nEpvX/UMu2Wbp74zUAK5q6WkHns7V0eWkdPbPzd3rxkTGybadYySumVzhcaJFbs5UrEkQ/+CK8gF5dnh/6ciIZ73gwQ927L1IitoxKLXYP3SjYdOrHHfTZhRRlFyrorafPk20B3HPD1y2G3qKZME5Jcf3t/HUC13/8tSd++vqFveMUTwAUxSUFI1QekR1+bIze3D9MF2aq6cPvG72CgnldWCFqyRw3lwH8ZMerjTD9ElRO7Gv44wNpC90aASqGfVlz/Rx17srQ57/UU26hkhQqUB7dBR71WmzQhHUnblGmVOEw0jhbV1n9OlXUDCIRGaNV5Jp43N516fN7JmnTHdfp7Hgy0luO4aMhtkLL8Bi3bUWYvzh5Mn1dTxrL6QmGuRhGL/TiTTxRoEdTszSaq9GR0NGA3KdkOz3hqSV3MIDhQ5IVX/Ivx3umBti2es2h4eZby7x8br1rkf7Mo90AqC8aQ3sJeNzqFRu+vSANAQe3PL7l0HGOAdwDCeZYvNKeoZp1Qfs6Aipndh86HmFRi0LAnEO47wsqM6cdfjh3jBPUzhZy7nvlUfFsamED1VQt6aISHVymXZ/B2aCtIG8AI8xfobj2d3en1wWVhOeHELKmLQ1s211s88comkv4UCwWyF787mJdYXtNfhKAXVqnKTq8QZvGAGGOfaTo5pGZ/PwbUCr5+DPr/1J92JNHr9aOl/F3iI5+O1nfybsGxoimvZ3ViWSluDITw3P37mypheDIPY0tw7+O/5ApbkYw+zpfaUVu32Pi98+defdUhEpZkRFq0aqyNh9FuL9hpYbEm6iwi0z2REd09ZmyENEbuhjDWzKvZXTqKYaBIr3tt5kuPtQBZFvEUwHt60vfCNu41XsksH9Ij1BMMz1Y0OOunHNShFIP5868g5zeXmuLwL9T4b6Q2+KejgAAAABJRU5ErkJggg==">Redis 集群<!----></h1> <div class="theme-vdoing-content content__default"><h1 id="redis-集群"><a href="#redis-集群" class="header-anchor">#</a> Redis 集群</h1> <blockquote><p><strong><a href="https://redis.io/topics/cluster-tutorial" target="_blank" rel="noopener noreferrer">Redis 集群(Redis Cluster)<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 是 Redis 官方提供的分布式数据库方案</strong>。</p> <p>既然是分布式,自然具备分布式系统的基本特性:可扩展、高可用、一致性。</p> <ul><li>Redis 集群通过划分 hash 槽来分区,进行数据分享。</li> <li>Redis 集群采用主从模型,提供复制和故障转移功能,来保证 Redis 集群的高可用。</li> <li>根据 CAP 理论,Consistency、Availability、Partition tolerance 三者不可兼得,而 Redis 集群的选择是 AP。Redis 集群节点间采用异步通信方式,不保证强一致性,尽力达到最终一致性。</li></ul></blockquote> <p><img src="https://raw.githubusercontent.com/dunwu/images/master/snap/20200713100613.png" alt="img"></p> <h2 id="_1-redis-cluster-分区"><a href="#_1-redis-cluster-分区" class="header-anchor">#</a> 1. Redis Cluster 分区</h2> <h3 id="_1-1-集群节点"><a href="#_1-1-集群节点" class="header-anchor">#</a> 1.1. 集群节点</h3> <p>Redis 集群由多个节点组成,节点刚启动时,彼此是相互独立的。<strong>节点通过握手( <code>CLUSTER MEET</code> 命令)来将其他节点添加到自己所处的集群中</strong>。</p> <p>向一个节点发送 <code>CLUSTER MEET</code> 命令,可以让当前节点与指定 IP、PORT 的节点进行握手,握手成功时,当前节点会将指定节点加入所在集群。</p> <p><strong>集群节点保存键值对以及过期时间的方式与单机 Redis 服务完全相同</strong>。</p> <p>Redis 集群节点分为主节点(master)和从节点(slave),其中主节点用于处理槽,而从节点则用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求。</p> <h3 id="_1-2-分配-hash-槽"><a href="#_1-2-分配-hash-槽" class="header-anchor">#</a> 1.2. 分配 Hash 槽</h3> <p>分布式存储需要解决的首要问题是把 <strong>整个数据集</strong> 按照 <strong>分区规则</strong> 映射到 <strong>多个节点</strong> 的问题,即把 <strong>数据集</strong> 划分到 <strong>多个节点</strong> 上,每个节点负责 <strong>整体数据</strong> 的一个 <strong>子集</strong>。</p> <p><strong>Redis 集群通过划分 hash 槽来将数据分区</strong>。Redis 集群通过分区的方式来保存数据库的键值对:<strong>集群的整个数据库被分为 16384 个哈希槽(slot)</strong>,数据库中的每个键都属于这 16384 个槽的其中一个,集群中的每个节点可以处理 0 个或最多 16384 个槽。<strong>如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态</strong>。</p> <p>通过向节点发送 <a href="https://redis.io/commands/cluster-addslots" target="_blank" rel="noopener noreferrer"><code>CLUSTER ADDSLOTS</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 命令,可以将一个或多个槽指派给节点负责。</p> <div class="language- extra-class"><pre class="language-text"><code>> CLUSTER ADDSLOTS 1 2 3
|
||
OK
|
||
</code></pre></div><p>集群中的每个节点负责一部分哈希槽,比如集群中有3个节点,则:</p> <ul><li>节点A存储的哈希槽范围是:0 – 5500</li> <li>节点B存储的哈希槽范围是:5501 – 11000</li> <li>节点C存储的哈希槽范围是:11001 – 16384</li></ul> <h3 id="_1-3-寻址"><a href="#_1-3-寻址" class="header-anchor">#</a> 1.3. 寻址</h3> <p>当客户端向节点发送与数据库键有关的命令时,接受命令的节点会<strong>计算出命令要处理的数据库属于哪个槽</strong>,并<strong>检查这个槽是否指派给了自己</strong>:</p> <ul><li>如果键所在的槽正好指派给了当前节点,那么当前节点直接执行命令。</li> <li>如果键所在的槽没有指派给当前节点,那么节点会向客户端返回一个 MOVED 错误,指引客户端重定向至正确的节点。</li></ul> <h4 id="_1-3-1-计算键属于哪个槽"><a href="#_1-3-1-计算键属于哪个槽" class="header-anchor">#</a> 1.3.1. 计算键属于哪个槽</h4> <p>决定一个 key 应该分配到那个槽的算法是:<strong>计算该 key 的 CRC16 结果再模 16834</strong>。</p> <div class="language- extra-class"><pre class="language-text"><code>HASH_SLOT = CRC16(KEY) mod 16384
|
||
</code></pre></div><p>当节点计算出 key 所属的槽为 i 之后,节点会根据以下条件判断槽是否由自己负责:</p> <div class="language- extra-class"><pre class="language-text"><code>clusterState.slots[i] == clusterState.myself
|
||
</code></pre></div><h4 id="_1-3-2-moved-错误"><a href="#_1-3-2-moved-错误" class="header-anchor">#</a> 1.3.2. MOVED 错误</h4> <p>当节点发现键所在的槽并非自己负责处理的时候,节点就会向客户端返回一个 <code>MOVED</code> 错误,指引客户端转向正在负责槽的节点。</p> <p><code>MOVED</code> 错误的格式为:</p> <div class="language- extra-class"><pre class="language-text"><code>MOVED <slot> <ip>:<port>
|
||
</code></pre></div><blockquote><p>个人理解:MOVED 这种操作有点类似 HTTP 协议中的重定向。</p></blockquote> <h3 id="_1-4-重新分区"><a href="#_1-4-重新分区" class="header-anchor">#</a> 1.4. 重新分区</h3> <p>Redis 集群的<strong>重新分区操作可以将任意数量的已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值对也会从源节点被移动到目标节点</strong>。</p> <p>重新分区操作<strong>可以在线进</strong>行,在重新分区的过程中,集群不需要下线,并且源节点和目标节点都可以继续处理命令请求。</p> <p>Redis 集群的重新分区操作由 Redis 集群管理软件 <strong>redis-trib</strong> 负责执行的,redis-trib 通过向源节点和目标节点发送命令来进行重新分区操作。</p> <p>重新分区的实现原理如下图所示:</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-cluster-trib.png" alt="img"></p> <h3 id="_1-5-ask-错误"><a href="#_1-5-ask-错误" class="header-anchor">#</a> 1.5. ASK 错误</h3> <p><code>ASK</code> 错误与 <code>MOVED</code> 的区别在于:<strong>ASK 错误只是两个节点在迁移槽的过程中使用的一种临时措施</strong>,在客户端收到关于槽 X 的 ASK 错误之后,客户端只会在接下来的一次命令请求中将关于槽 X 的命令请求发送至 ASK 错误所指示的节点,但这种转向不会对客户端今后发送关于槽 X 的命令请求产生任何影响,客户端仍然会将关于槽 X 的命令请求发送至目前负责处理槽 X 的节点,除非 ASK 错误再次出现。</p> <p>判断 ASK 错误的过程如下图所示:</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-ask.png" alt="img"></p> <h2 id="_2-redis-cluster-故障转移"><a href="#_2-redis-cluster-故障转移" class="header-anchor">#</a> 2. Redis Cluster 故障转移</h2> <h3 id="_2-1-复制"><a href="#_2-1-复制" class="header-anchor">#</a> 2.1. 复制</h3> <p>Redis 复制机制可以参考:<a href="/db-tutorial/12.数据库/05.KV数据库/01.Redis/docs/05.KV数据库/01.Redis/05.Redis复制.html">Redis 复制</a></p> <h3 id="_2-2-故障检测"><a href="#_2-2-故障检测" class="header-anchor">#</a> 2.2. 故障检测</h3> <p><strong>集群中每个节点都会定期向集群中的其他节点发送 PING 消息,以此来检测对方是否在线</strong>。</p> <p>节点的状态信息可以分为:</p> <ul><li><p>在线状态;</p></li> <li><p>下线状态(FAIL);</p></li> <li><p>疑似下线状态(PFAIL),即在规定的时间内,没有应答 PING 消息;</p></li></ul> <h3 id="_2-3-故障转移"><a href="#_2-3-故障转移" class="header-anchor">#</a> 2.3. 故障转移</h3> <ol><li>下线主节点的所有从节点中,会有一个从节点被选中。</li> <li>被选中的从节点会执行 <code>SLAVEOF no one</code> 命令,成为新的主节点。</li> <li>新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己。</li> <li>新的主节点向集群广播一条 PONG 消息,告知其他节点这个从节点已变成主节点。</li></ol> <h3 id="_2-4-选举新的主节点"><a href="#_2-4-选举新的主节点" class="header-anchor">#</a> 2.4. 选举新的主节点</h3> <p>Redis 集群选举新的主节点流程基于<a href="https://www.jianshu.com/p/8e4bbe7e276c" target="_blank" rel="noopener noreferrer">共识算法:Raft<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="_3-redis-cluster-通信"><a href="#_3-redis-cluster-通信" class="header-anchor">#</a> 3. Redis Cluster 通信</h2> <p>集群中的节点通过发送和接收消息来进行通信。</p> <p>Redis 集群节点发送的消息主要有以下五种:</p> <ul><li><code>MEET</code> - 请求接收方加入发送方所在的集群。</li> <li><code>PING</code> - 集群中每个节点每隔一段时间(默认为一秒)从已知节点列表中随机选出五个节点,然后对这五个节点中最久没联系的节点发送 PING 消息,以此检测被选中的节点是否在线。</li> <li><code>PONG</code> - 当接收方收到发送方发来的 MEET 消息或 PING 消息时,会返回一条 PONG 消息作为应答。</li> <li><code>FAIL</code> - 当一个主节点 A 判断另一个主节点 B 已经进入 FAIL 状态时,节点 A 会向集群广播一条关于节点 B 的 FAIL 消息,所有收到这条消息的节点都会立即将节点 B 标记为已下线。</li> <li><code>PUBLISH</code> - 当节点收到一个 PUBLISH 命令时,节点会执行这个命令,并向集群广播一条 PUBLISH 消息,所有接受到这条消息的节点都会执行相同的 PUBLISH 命令。</li></ul> <h2 id="_4-redis-cluster-应用"><a href="#_4-redis-cluster-应用" class="header-anchor">#</a> 4. Redis Cluster 应用</h2> <h3 id="_4-1-集群功能限制"><a href="#_4-1-集群功能限制" class="header-anchor">#</a> 4.1. 集群功能限制</h3> <p>Redis 集群相对 <strong>单机</strong>,存在一些功能限制,需要 <strong>开发人员</strong> 提前了解,在使用时做好规避。</p> <ul><li><p><code>key</code> <strong>批量操作</strong> 支持有限:类似 <code>mset</code>、<code>mget</code> 操作,目前只支持对具有相同 <code>slot</code> 值的 <code>key</code> 执行 <strong>批量操作</strong>。对于 <strong>映射为不同</strong> <code>slot</code> 值的 <code>key</code> 由于执行 <code>mget</code>、<code>mget</code> 等操作可能存在于多个节点上,因此不被支持。</p></li> <li><p><code>key</code> <strong>事务操作</strong> 支持有限:只支持 <strong>多</strong> <code>key</code> 在 <strong>同一节点上</strong> 的 <strong>事务操作</strong>,当多个 <code>key</code> 分布在 <strong>不同</strong> 的节点上时 <strong>无法</strong> 使用事务功能。</p></li> <li><p><code>key</code> 作为 <strong>数据分区</strong> 的最小粒度,不能将一个 <strong>大的键值</strong> 对象如 <code>hash</code>、<code>list</code> 等映射到 <strong>不同的节点</strong>。</p></li> <li><p>不支持 <strong>多数据库空间</strong>:<strong>单机</strong> 下的 Redis 可以支持 <code>16</code> 个数据库(<code>db0 ~ db15</code>),<strong>集群模式</strong> 下只能使用 <strong>一个</strong> 数据库空间,即 <code>db0</code>。</p></li> <li><p><strong>复制结构</strong> 只支持一层:<strong>从节点</strong> 只能复制 <strong>主节点</strong>,不支持 <strong>嵌套树状复制</strong> 结构。</p></li></ul> <h3 id="_4-2-集群规模限制"><a href="#_4-2-集群规模限制" class="header-anchor">#</a> 4.2. 集群规模限制</h3> <p>Redis Cluster 的优点是易于使用。分区、主从复制、弹性扩容这些功能都可以做到自动化,通过简单的部署就可以获得一个大容量、高可靠、高可用的 Redis 集群,并且对于应用来说,近乎于是透明的。</p> <p>所以,<strong>Redis Cluster 非常适合构建中小规模 Redis 集群</strong>,这里的中小规模指的是,大概几个到几十个节点这样规模的 Redis 集群。</p> <p>但是 Redis Cluster 不太适合构建超大规模集群,主要原因是,它采用了去中心化的设计。</p> <p>Redis 的每个节点上,都保存了所有槽和节点的映射关系表,客户端可以访问任意一个节点,再通过重定向命令,找到数据所在的那个节点。那么,这个映射关系表是如何更新的呢?Redis Cluster 采用了一种去中心化的流言 (Gossip) 协议来传播集群配置的变化。</p> <p>Gossip 协议的优点是去中心化;缺点是传播速度慢,并且是集群规模越大,传播的越慢。</p> <h3 id="_4-3-集群配置"><a href="#_4-3-集群配置" class="header-anchor">#</a> 4.3. 集群配置</h3> <p>我们后面会部署一个 Redis 集群作为例子,在那之前,先介绍一下集群在 redis.conf 中的参数。</p> <ul><li><strong>cluster-enabled</strong> <code><yes/no></code> - 如果配置”yes”则开启集群功能,此 redis 实例作为集群的一个节点,否则,它是一个普通的单一的 redis 实例。</li> <li><strong>cluster-config-file</strong> <code><filename></code> - 注意:虽然此配置的名字叫“集群配置文件”,但是此配置文件不能人工编辑,它是集群节点自动维护的文件,主要用于记录集群中有哪些节点、他们的状态以及一些持久化参数等,方便在重启时恢复这些状态。通常是在收到请求之后这个文件就会被更新。</li> <li><strong>cluster-node-timeout</strong> <code><milliseconds></code> - 这是集群中的节点能够失联的最大时间,超过这个时间,该节点就会被认为故障。如果主节点超过这个时间还是不可达,则用它的从节点将启动故障迁移,升级成主节点。注意,任何一个节点在这个时间之内如果还是没有连上大部分的主节点,则此节点将停止接收任何请求。</li> <li><strong>cluster-slave-validity-factor</strong> <code><factor></code> - 如果设置成0,则无论从节点与主节点失联多久,从节点都会尝试升级成主节点。如果设置成正数,则 cluster-node-timeout 乘以 cluster-slave-validity-factor 得到的时间,是从节点与主节点失联后,此从节点数据有效的最长时间,超过这个时间,从节点不会启动故障迁移。假设 cluster-node-timeout=5,cluster-slave-validity-factor=10,则如果从节点跟主节点失联超过 50 秒,此从节点不能成为主节点。注意,如果此参数配置为非 0,将可能出现由于某主节点失联却没有从节点能顶上的情况,从而导致集群不能正常工作,在这种情况下,只有等到原来的主节点重新回归到集群,集群才恢复运作。</li> <li><strong>cluster-migration-barrier</strong> <code><count></code> - 主节点需要的最小从节点数,只有达到这个数,主节点失败时,它从节点才会进行迁移。更详细介绍可以看本教程后面关于副本迁移到部分。</li> <li><strong>cluster-require-full-coverage</strong> <code><yes/no></code> - 在部分 key 所在的节点不可用时,如果此参数设置为”yes”(默认值), 则整个集群停止接受操作;如果此参数设置为”no”,则集群依然为可达节点上的 key 提供读操作。</li></ul> <h2 id="_5-其他-redis-集群方案"><a href="#_5-其他-redis-集群方案" class="header-anchor">#</a> 5. 其他 Redis 集群方案</h2> <p>Redis Cluster 不太适合用于大规模集群,所以,如果要构建超大 Redis 集群,需要选择替代方案。一般有三种方案类型:</p> <ul><li>客户端分区方案</li> <li>代理分区方案</li> <li>查询路由方案</li></ul> <h3 id="_5-1-客户端分区方案"><a href="#_5-1-客户端分区方案" class="header-anchor">#</a> 5.1. 客户端分区方案</h3> <p><strong>客户端</strong> 就已经决定数据会被 <strong>存储</strong> 到哪个 Redis 节点或者从哪个 Redis 节点 <strong>读取数据</strong>。其主要思想是采用 <strong>哈希算法</strong> 将 Redis 数据的 <code>key</code> 进行散列,通过 <code>hash</code> 函数,特定的 <code>key</code>会 <strong>映射</strong> 到特定的 Redis 节点上。</p> <p><strong>客户端分区方案</strong> 的代表为 Redis Sharding,Redis Sharding 是 Redis Cluster 出来之前,业界普遍使用的 Redis <strong>多实例集群</strong> 方法。Java 的 Redis 客户端驱动库 <a href="https://github.com/redis/jedis" target="_blank" rel="noopener noreferrer"><strong>Jedis</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>,支持 Redis Sharding 功能,即 ShardedJedis 以及 <strong>结合缓存池</strong> 的 ShardedJedisPool。</p> <ul><li><p><strong>优点</strong>:不使用 <strong>第三方中间件</strong>,<strong>分区逻辑</strong> 可控,<strong>配置</strong> 简单,节点之间无关联,容易 <strong>线性扩展</strong>,灵活性强。</p></li> <li><p><strong>缺点</strong>:<strong>客户端</strong> 无法 <strong>动态增删</strong> 服务节点,客户端需要自行维护 <strong>分发逻辑</strong>,客户端之间 <strong>无连接共享</strong>,会造成 <strong>连接浪费</strong>。</p></li></ul> <h3 id="_5-2-代理分区方案"><a href="#_5-2-代理分区方案" class="header-anchor">#</a> 5.2. 代理分区方案</h3> <p><strong>客户端</strong> 发送请求到一个 <strong>代理组件</strong>,<strong>代理</strong> 解析 <strong>客户端</strong> 的数据,并将请求转发至正确的节点,最后将结果回复给客户端。</p> <ul><li><strong>优点</strong>:简化 <strong>客户端</strong> 的分布式逻辑,<strong>客户端</strong> 透明接入,切换成本低,代理的 <strong>转发</strong> 和 <strong>存储</strong> 分离。</li> <li><strong>缺点</strong>:多了一层 <strong>代理层</strong>,加重了 <strong>架构部署复杂度</strong> 和 <strong>性能损耗</strong>。</li></ul> <p><strong>代理分区</strong> 主流实现的有方案有 <strong><a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener noreferrer">Twemproxy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></strong> 和 <a href="https://github.com/CodisLabs/codis" target="_blank" rel="noopener noreferrer"><strong>Codis</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。</p> <h4 id="_5-2-1-twemproxy"><a href="#_5-2-1-twemproxy" class="header-anchor">#</a> 5.2.1. Twemproxy</h4> <p><strong><a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener noreferrer">Twemproxy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></strong> 也叫 <code>nutcraker</code>,是 Twitter 开源的一个 Redis 和 Memcache 的 <strong>中间代理服务器</strong> 程序。</p> <p><strong><a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener noreferrer">Twemproxy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></strong> 作为 <strong>代理</strong>,可接受来自多个程序的访问,按照 <strong>路由规则</strong>,转发给后台的各个 Redis 服务器,再原路返回。<strong><a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener noreferrer">Twemproxy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></strong> 存在 <strong>单点故障</strong> 问题,需要结合 Lvs 和 Keepalived 做 <strong>高可用方案</strong>。</p> <ul><li><strong>优点</strong>:应用范围广,稳定性较高,中间代理层 <strong>高可用</strong>。</li> <li><strong>缺点</strong>:无法平滑地 <strong>水平扩容/缩容</strong>,无 <strong>可视化管理界面</strong>,运维不友好,出现故障,不能 <strong>自动转移</strong>。</li></ul> <h4 id="_5-2-2-codis"><a href="#_5-2-2-codis" class="header-anchor">#</a> 5.2.2. Codis</h4> <p><a href="https://github.com/CodisLabs/codis" target="_blank" rel="noopener noreferrer"><strong>Codis</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 是一个 <strong>分布式</strong> Redis 解决方案,对于上层应用来说,连接 Codis-Proxy 和直接连接 <strong>原生的</strong> Redis-Server 没有的区别。<a href="https://github.com/CodisLabs/codis" target="_blank" rel="noopener noreferrer"><strong>Codis</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 底层会 <strong>处理请求的转发</strong>,不停机的进行 <strong>数据迁移</strong> 等工作。<a href="https://github.com/CodisLabs/codis" target="_blank" rel="noopener noreferrer"><strong>Codis</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 采用了无状态的 <strong>代理层</strong>,对于 <strong>客户端</strong> 来说,一切都是透明的。</p> <ul><li><p><strong>优点</strong>:实现了上层 Proxy 和底层 Redis 的 <strong>高可用</strong>,<strong>数据分区</strong> 和 <strong>自动平衡</strong>,提供 <strong>命令行接口</strong> 和 RESTful API,提供 <strong>监控</strong> 和 <strong>管理</strong> 界面,可以动态 <strong>添加</strong> 和 <strong>删除</strong> Redis 节点。</p></li> <li><p><strong>缺点</strong>:<strong>部署架构</strong> 和 <strong>配置</strong> 复杂,不支持 <strong>跨机房</strong> 和 <strong>多租户</strong>,不支持 <strong>鉴权管理</strong>。</p></li></ul> <h3 id="_5-3-查询路由方案"><a href="#_5-3-查询路由方案" class="header-anchor">#</a> 5.3. 查询路由方案</h3> <p><strong>客户端随机地</strong> 请求任意一个 Redis 实例,然后由 Redis 将请求 <strong>转发</strong> 给 <strong>正确</strong> 的 Redis 节点。Redis Cluster 实现了一种 <strong>混合形式</strong> 的 <strong>查询路由</strong>,但并不是 <strong>直接</strong> 将请求从一个 Redis 节点 <strong>转发</strong> 到另一个 Redis 节点,而是在 <strong>客户端</strong> 的帮助下直接 <strong>重定向</strong>( <code>redirected</code>)到正确的 Redis 节点。</p> <ul><li><p><strong>优点</strong>:<strong>去中心化</strong>,数据按照 <strong>槽</strong> 存储分布在多个 Redis 实例上,可以平滑的进行节点 <strong>扩容/缩容</strong>,支持 <strong>高可用</strong> 和 <strong>自动故障转移</strong>,运维成本低。</p></li> <li><p><strong>缺点</strong>:重度依赖 Redis-trib 工具,缺乏 <strong>监控管理</strong>,需要依赖 Smart Client (<strong>维护连接</strong>,<strong>缓存路由表</strong>,<code>MultiOp</code> 和 <code>Pipeline</code> 支持)。Failover 节点的 <strong>检测过慢</strong>,不如有 <strong>中心节点</strong> 的集群及时(如 ZooKeeper)。Gossip 消息采用广播方式,集群规模越大,开销越大。无法根据统计区分 <strong>冷热数据</strong>。</p></li></ul> <h2 id="_6-参考资料"><a href="#_6-参考资料" class="header-anchor">#</a> 6. 参考资料</h2> <ul><li><strong>官网</strong> <ul><li><a href="https://redis.io/" target="_blank" rel="noopener noreferrer">Redis 官网<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/antirez/redis" target="_blank" rel="noopener noreferrer">Redis github<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="http://redis.cn/" target="_blank" rel="noopener noreferrer">Redis 官方文档中文版<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><strong>中间件</strong> <ul><li><a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener noreferrer">Twemproxy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/CodisLabs/codis" target="_blank" rel="noopener noreferrer">Codis<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><strong>书籍</strong> <ul><li><a href="https://item.jd.com/11791607.html" target="_blank" rel="noopener noreferrer">《Redis 实战》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://item.jd.com/11486101.html" target="_blank" rel="noopener noreferrer">《Redis 设计与实现》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><strong>教程</strong> <ul><li><a href="https://time.geekbang.org/column/intro/100046801" target="_blank" rel="noopener noreferrer">后端存储实战课<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><strong>文章</strong> <ul><li><a href="http://ifeve.com/redis-cluster-tutorial/" target="_blank" rel="noopener noreferrer">Redis 集群教程<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://www.jianshu.com/p/c869feb5581d" target="_blank" rel="noopener noreferrer">Redis 集群的原理和搭建<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/5b8fc5536fb9a05d2d01fb11" target="_blank" rel="noopener noreferrer">深入剖析 Redis 系列(三) - Redis 集群模式搭建与原理详解<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li></ul></div></div> <div class="page-edit"><div class="edit-link"><a href="https://github.com/dunwu/db-tutorial/edit/master/docs/12.数据库/05.KV数据库/01.Redis/07.Redis集群.md" target="_blank" rel="noopener noreferrer">📝 帮助改善此页面!</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="tags"><a href="/db-tutorial/tags/?tag=%E6%95%B0%E6%8D%AE%E5%BA%93" title="标签">#数据库</a><a href="/db-tutorial/tags/?tag=KV%E6%95%B0%E6%8D%AE%E5%BA%93" title="标签">#KV数据库</a><a href="/db-tutorial/tags/?tag=Redis" title="标签">#Redis</a><a href="/db-tutorial/tags/?tag=%E9%9B%86%E7%BE%A4" title="标签">#集群</a></div> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2024/10/09, 07:16:02</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/db-tutorial/pages/615afe/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">Redis 哨兵</div></a> <a href="/db-tutorial/pages/1fc9c4/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">Redis 实战</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
|
||
←
|
||
<a href="/db-tutorial/pages/615afe/" class="prev">Redis 哨兵</a></span> <span class="next"><a href="/db-tutorial/pages/1fc9c4/">Redis 实战</a>→
|
||
</span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/db-tutorial/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/db-tutorial/pages/b59ba2/"><div>
|
||
HBase Java API 管理功能
|
||
<!----></div></a> <span class="date">04-13</span></dt></dl><dl><dd>02</dd> <dt><a href="/db-tutorial/pages/ce5ca0/"><div>
|
||
HBase Java API 其他高级特性
|
||
<!----></div></a> <span class="date">03-31</span></dt></dl><dl><dd>03</dd> <dt><a href="/db-tutorial/pages/c8cfeb/"><div>
|
||
HBase 数据模型
|
||
<!----></div></a> <span class="date">03-16</span></dt></dl> <dl><dd></dd> <dt><a href="/db-tutorial/archives/" class="more">更多文章></a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="mailto:forbreak@163.com" title="发邮件" target="_blank" class="iconfont icon-youjian"></a><a href="https://github.com/dunwu" title="GitHub" target="_blank" class="iconfont icon-github"></a></div>
|
||
Theme by
|
||
<a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a>
|
||
| Copyright © 2019-2024
|
||
<span>钝悟(dunwu) | CC-BY-SA-4.0</span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
|
||
跟随系统
|
||
</li><li class="iconfont icon-rijianmoshi">
|
||
浅色模式
|
||
</li><li class="iconfont icon-yejianmoshi">
|
||
深色模式
|
||
</li><li class="iconfont icon-yuedu">
|
||
阅读模式
|
||
</li></ul></div></div> <!----> <!----> <div class="custom-html-window custom-html-window-rb" style="display:;"><div class="custom-wrapper"><span class="close-but">×</span> <div>
|
||
<div class="wwads-cn wwads-vertical windowRB" data-id="261" style="max-width:160px;
|
||
min-width: auto;min-height:auto;"></div>
|
||
<style>
|
||
.windowRB{ padding: 0;}
|
||
.windowRB .wwads-img{margin-top: 10px;}
|
||
.windowRB .wwads-content{margin: 0 10px 40px 10px;}
|
||
.custom-html-window-rb .close-but{
|
||
display: none;
|
||
}
|
||
</style>
|
||
</div></div></div></div><div class="global-ui"><div></div></div></div>
|
||
<script src="/db-tutorial/assets/js/app.be3f2e92.js" defer></script><script src="/db-tutorial/assets/js/2.aded268b.js" defer></script><script src="/db-tutorial/assets/js/50.ee6f08b7.js" defer></script>
|
||
</body>
|
||
</html>
|