<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Redis on codedump notes</title>
    <link>https://www.codedump.info/zh/tags/redis/</link>
    <description>Recent content in Redis on codedump notes</description>
    <generator>Hugo</generator>
    <language>zh</language>
    <lastBuildDate>Sun, 21 Apr 2019 22:52:16 +0800</lastBuildDate>
    <atom:link href="https://www.codedump.info/zh/tags/redis/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>redis高可用原理</title>
      <link>https://www.codedump.info/zh/post/20190409-redis-sentinel/</link>
      <pubDate>Sun, 21 Apr 2019 22:52:16 +0800</pubDate>
      <guid>https://www.codedump.info/zh/post/20190409-redis-sentinel/</guid>
      <description>&lt;p&gt;redis中为了实现高可用（High Availability，简称HA），采用了如下两个方式：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;主从复制数据。&lt;/li&gt;&#xA;&lt;li&gt;采用哨兵监控数据节点的运行情况，一旦主节点出现问题由从节点顶上继续进行服务。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 class=&#34;heading&#34; id=&#34;主从复制&#34;&gt;&#xA;  主从复制&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e4%b8%bb%e4%bb%8e%e5%a4%8d%e5%88%b6&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;redis中主从节点复制数据有全量复制和部分复制之分。&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;旧版本全量复制功能的实现&#34;&gt;&#xA;  旧版本全量复制功能的实现&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e6%97%a7%e7%89%88%e6%9c%ac%e5%85%a8%e9%87%8f%e5%a4%8d%e5%88%b6%e5%8a%9f%e8%83%bd%e7%9a%84%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;全量复制使用snyc命令来实现，其流程是：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;从服务器向主服务器发送sync命令。&lt;/li&gt;&#xA;&lt;li&gt;主服务器在收到sync命令之后，调用bgsave命令生成最新的rdb文件，将这个文件同步给从服务器，这样从服务器载入这个rdb文件之后，状态就会和主服务器执行bgsave命令时候的一致。&lt;/li&gt;&#xA;&lt;li&gt;主服务器将保存在命令缓冲区中的写命令同步给从服务器，从服务器执行这些命令，这样从服务器的状态就跟主服务器当前状态一致了。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;figure class=&#34;&#34;&gt;&#xA;&#xA;    &lt;div&gt;&#xA;        &lt;img loading=&#34;lazy&#34; alt=&#34;sync&#34; src=&#34;https://www.codedump.info/media/imgs/20190409-redis-sentinel/sync.png&#34; &gt;&#xA;    &lt;/div&gt;&#xA;&#xA;    &#xA;    &lt;div class=&#34;caption-container&#34;&gt;&#xA;        &lt;figcaption&gt; sync &lt;/figcaption&gt;&#xA;    &lt;/div&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;旧版本全量复制功能，其最大的问题是从服务器断线重连时，即便在从服务器上已经有一部分数据了，也需要进行全量复制，这样做的效率很低，于是新版本的redis在这部分做了改进。&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;新版本全量复制功能的实现&#34;&gt;&#xA;  新版本全量复制功能的实现&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e6%96%b0%e7%89%88%e6%9c%ac%e5%85%a8%e9%87%8f%e5%a4%8d%e5%88%b6%e5%8a%9f%e8%83%bd%e7%9a%84%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;新版本redis使用psync命令来代替sync命令，该命令既可以实现完整全同步也可以实现部分同步。&lt;/p&gt;&#xA;&lt;h3 class=&#34;heading&#34; id=&#34;复制偏移量&#34;&gt;&#xA;  复制偏移量&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e5%a4%8d%e5%88%b6%e5%81%8f%e7%a7%bb%e9%87%8f&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;执行复制的双方，主从服务器，分别会维护一个复制偏移量：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;主服务器每次向从服务器同步了N字节数据之后，将修改自己的复制偏移量+N。&lt;/li&gt;&#xA;&lt;li&gt;从服务器每次从主服务器同步了N字节数据之后，将修改自己的复制偏移量+N。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;复制积压缓冲区&#34;&gt;&#xA;  复制积压缓冲区&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e5%a4%8d%e5%88%b6%e7%a7%af%e5%8e%8b%e7%bc%93%e5%86%b2%e5%8c%ba&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;主服务器内部维护了一个固定长度的先进先出队列做为复制积压缓冲区，其默认大小为1MB。&lt;/p&gt;&#xA;&lt;p&gt;在主服务器进行命令传播时，不仅会将写命令同步到从服务器，还会将写命令写入复制积压缓冲区。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;figure class=&#34;&#34;&gt;&#xA;&#xA;    &lt;div&gt;&#xA;        &lt;img loading=&#34;lazy&#34; alt=&#34;replication-backlog&#34; src=&#34;https://www.codedump.info/media/imgs/20190409-redis-sentinel/replication-backlog.png&#34; &gt;&#xA;    &lt;/div&gt;&#xA;&#xA;    &#xA;    &lt;div class=&#34;caption-container&#34;&gt;&#xA;        &lt;figcaption&gt; replication-backlog &lt;/figcaption&gt;&#xA;    &lt;/div&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;服务器运行id&#34;&gt;&#xA;  服务器运行ID&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e6%9c%8d%e5%8a%a1%e5%99%a8%e8%bf%90%e8%a1%8cid&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;每个redis服务器，都有其运行ID，运行ID由服务器在启动时自动生成，主服务器会将自己的运行ID发送给从服务器，而从服务器会将主服务器的运行ID保存起来。&lt;/p&gt;&#xA;&lt;p&gt;从服务器redis断线重连之后进行同步时，就是根据运行ID来判断同步的进度：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如果从服务器上面保存的主服务器运行ID与当前主服务器运行ID一致，则认为这一次断线重连连接的是之前复制的主服务器，主服务器可以继续尝试部分同步操作。&lt;/li&gt;&#xA;&lt;li&gt;否则，如果前后两次主服务器运行ID不相同，则认为是完成全同步流程。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 class=&#34;heading&#34; id=&#34;psync命令流程&#34;&gt;&#xA;  psync命令流程&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#psync%e5%91%bd%e4%bb%a4%e6%b5%81%e7%a8%8b&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;有了前面的准备，下面开始分析psync命令的流程：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如果从服务器之前没有复制过任何主服务器，或者之前执行过slaveof no one命令，那么从服务器就会向主服务器发送psync ? -1命令，请求主服务器进行数据的全量同步。&lt;/li&gt;&#xA;&lt;li&gt;否则，如果前面从服务器已经同步过部分数据，那么从服务器向主服务器发送psync &amp;lt;runid&amp;gt; &amp;lt;offset&amp;gt;命令，其中runid是上一次主服务器的运行id，offset是当前从服务器的复制偏移量。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;前面两种情况主服务器收到psync命令之后，会出现以下三种可能：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;主服务器返回+fullresync &amp;lt;runid&amp;gt; &amp;lt;offset&amp;gt;回复，表示主服务器要求与从服务器进行完整的数据全量同步操作。其中，runid是当前主服务器运行id，而offset是当前主服务器的复制偏移量。&lt;/li&gt;&#xA;&lt;li&gt;如果主服务器应答+continue，那么表示主服务器与从服务器进行部分数据同步操作，将从服务器缺失的数据同步过来即可。&lt;/li&gt;&#xA;&lt;li&gt;如果主服务器应答-err，那么表示主服务器版本低于2.8，识别不了psync命令，此时从服务器将向主服务器发送sync命令，执行完整的全量数据同步。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;figure class=&#34;&#34;&gt;&#xA;&#xA;    &lt;div&gt;&#xA;        &lt;img loading=&#34;lazy&#34; alt=&#34;psync&#34; src=&#34;https://www.codedump.info/media/imgs/20190409-redis-sentinel/psync.png&#34; &gt;&#xA;    &lt;/div&gt;&#xA;&#xA;    &#xA;    &lt;div class=&#34;caption-container&#34;&gt;&#xA;        &lt;figcaption&gt; psync &lt;/figcaption&gt;&#xA;    &lt;/div&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&lt;/p&gt;&#xA;&lt;h1 class=&#34;heading&#34; id=&#34;哨兵机制概述&#34;&gt;&#xA;  哨兵机制概述&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e5%93%a8%e5%85%b5%e6%9c%ba%e5%88%b6%e6%a6%82%e8%bf%b0&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;redis使用哨兵机制来实现高可用(HA)，其大概工作原理是：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;redis使用一组哨兵（sentinel）节点来监控主从redis服务的可用性。&lt;/li&gt;&#xA;&lt;li&gt;一旦发现redis主节点失效，将选举出一个哨兵节点作为领导者（leader）。&lt;/li&gt;&#xA;&lt;li&gt;哨兵领导者再从剩余的从redis节点中选出一个redis节点作为新的主redis节点对外服务。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以上将redis节点分为两类：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;哨兵节点（sentinel）：负责监控节点的运行情况。&lt;/li&gt;&#xA;&lt;li&gt;数据节点：即正常服务客户端请求的redis节点，有主从之分。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以上是大体的流程，这个流程需要解决以下几个问题：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
