Raft 只读操作优化

为什么需要优化只读操作

raft是一个为分布式集群达成一致性的协议。对于集群需要保证一致性的数据,每次一操作其实都要确认此操作是否在集群中达成了一致。从是否会改变数据的角度,操作就分两个只读操作写操作。只读操作顾名思义就是不会对数据做任何的改动。写操作包含了增删改等需要修改数据的操作,通俗说就是这次操作处理完后,数据有可能跟操作前不一样。

正是因为只读操作不对数据进行修改,所以raft可以优化只读操作。

  1. 因为只要客户端请求的是现集群真正的leader,那么获取到的数据就不会有错误。一个只读操作没有必要征求整个raft集群的共识。毕竟使用raft达成一个操作的共识还需要多节点网络请求与log持久化落磁盘等开销。
  2. 在恢复和安装快照,或者是raft集群加入新节点同步log与数据的时,因为只读操作并没有改变数据,所以不需要还原这些操作也能保持数据的完整与一致,提高数据恢复的效率。

如何优化

优化只读操作的核心就是保证此时请求到该集群leader确实是能够向集群中法定人数的节点commit log成功。否则用户可能会读到陈旧的数据信息,无法保证线性一致。

用论文[1]中的话说就是

  1. leader必须拥有最新被提交的日志的信息
  2. 在处理只读请求前,leader必须确认自己是否已经被替换掉了

围绕这一核心目标,raft的作者在他PhD论文[2]中提到了两种优化的方法。

一. 使用readIndex

  1. 使用commitIndex做为readIndex。这里需要注意⚠️:当一个leader刚被当选时,虽然他肯定拥有最完整的信息,但leader无法确认自己的commitIndex是最新的。所以这个leader必须发一个no-op的空白log。直到这个空白log被commit了,保证了commitIndex为最新的。再将最新的commitIndex做为readIndex。
  2. 发起一次心跳,当收集到这次心跳返回ack中的commitIndex >= readIndex 且 commitIndex达到法定人数时。确认leader拥有最新被提交的日志且自己就是集群中的合法leader。
  3. leader的状态机至少执行到readIndex,保证线性一致性。
  4. 返回给状态机,执行这个只读的操作给客户。

readIndex这种方法,虽然避免不了网络请求的开销,但是减少了raft的log,也避免了读操作落磁盘的开销。

此方法实现以后,用户可以向follower请求只读操作,以保证负载均衡,增强系统读的吞吐率。这里需要注意,follower的数据可能落后当前leader很多,或者网络分区后跟随了错误的leader。所以,leader必须提供一个接口以返回当前的readIndex。follower请求这个接口,拿到当前的readIndex,然后leader执行1-2,被请求的follower在自己的状态机中执行3-4步。

但是我觉得这种负载均衡的方法并不是很巧妙。第一,增加了系统复杂度,第二,有了读放大,多了请求leader的网络操作。第三,这种方法并不能保证用户的写操作负载均衡。

现在系统一般使用对集群分组,对数据分片的方法来做负载均衡。这样既不会增加raft协议的复杂度,同时对读写操作都做了负载均衡。

二. 使用时钟(lease read)

方法二就是使用租期(lease)时间。在租期未过期时,在不进行任何网络请求下,保证用户只读请求。

首先还是要记录leader的commitIndex作为readIndex。但是不会专门发起一次心跳(一.中的2)。在租期不过期的情况下,保证leader的状态机至少执行到readIndex,给用户返回只读操作。

租期其实就是选举的时间差。当leader收到法定人数的心跳后,那么在raft系统设置超时选举(election timeout)这段时间内,自己的数据肯定是正确的。因为在这段时间里,肯定不会有新的leader产生。

这里使用论文[2]中的一副图来说明情况

因为要考虑到进程调度,垃圾回收,虚拟机迁移,时钟频率不同等种种原因,需要设置一个bound(bound是大于1的)。其中start为leader向集群follower发送心跳的时间点。那么租期为:

当收到法定人数的心跳点后,延长一个租期(lease_time)。虽然使用lease这种方法减少了时钟开销,但是如果这里的bound设置与现实不符,或者出现时钟严重漂移等问题。仍会导致旧leader可能给客户返回陈旧数据。

作者在文章[2]中最后又提出了一种方法来避免这种情况。

服务器在返回apply日志时,把这个日志对应的index也一并返回给用户,用户把这个日志的index保存起来,客户将跟踪与他们所看到的结果相对应的最新索引,并在每次请求时将这些信息提供给服务端。如果服务端收到的客户端请求的index大于服务器最新的applied的日志的index,则服务器不会为该请求提供服务。

不过这个描述我没太看懂。。因为要保证所有客户端都能知道最新的applied 的index,感觉这种情况才能避免。

TiKV中提供了一种解决方案[3],有点像一和二的结合体。不同的是在每次写操作时,进行租期的续约。如果长时间没有写操作,租期过期时,使用方法一(readIndex)进行。

[1] Ongaro D, Ousterhout J. In search of an understandable consensus algorithm (extended version)[J]. 2013.

[2] Ongaro D. Consensus: Bridging theory and practice[D]. Stanford University, 2014.

[3] https://pingcap.com/blog-cn/lease-read/

当前只读状态:是_Raft 只读(read-only)优化相关推荐

  1. java 数据库 事务 只读_java – odd SQLException – 无法检索转换只读状态服务器

    我有一个 Quartz作业,每5分钟一次在MySQL数据库中执行一个存储过程,由于某种原因,3个执行中有1个失败,并提供了这个奇怪的异常.我搜索并搜索了这个异常是什么意思,但是我找不到解决方案.这是完 ...

  2. HTML文本框只读状态

    有时文本框内的信息不允许更改,只能是只读状态,只要在input标签中加入readonly即可. <input type="text" style="width: 3 ...

  3. VS2010 winform中的文本框怎样设置为只读状态

    在用C#编写winform时,我们常常需要用文本框来显示一些东西,可是当客户使用时,可能会在文本框里面输入一些东西,就有可能会影响程序的运行,那我们是否可以将文本框设为只读状态,使其不能输入?答案是肯 ...

  4. mysql data文件夹取消只读_Linux文件目录变只读(Read-only file system)导致mysql启动失败...

    背景 今天准备调试一个很久没打开的项目时,页面无法展示信息,经排查是因为数据库停止,查看运行状态发现以下异常. Jun 15 15:30:58 sccprocduat10 systemd[1]: St ...

  5. 嵌入式之SD卡/U盘只读问题解决方案(FAT只读修复方式)

    SD卡异常问题分类解决 嵌入式存储对SD卡的使用是比较普遍的,如何把SD卡的性能用到极致避免出现各类问题,需要大家在代码的设计过程中实现异常错误处理. SD卡问题主要有以下3个 1.SD卡无法识别 2 ...

  6. Excel文档打开显示只读,如何取消只读功能?

    Excel文档打开显示只读,如何取消只读功能? 目录 Excel文档打开显示只读,如何取消只读功能? 1.打开文档点击[保存]时,自动弹出对话框显示[只读],只能另存文档,比较麻烦. 2.将该文档关闭 ...

  7. easyui中动态使datebox、combobox为只读状态

    $("#achievement_position_id").datebox('readonly',true); $('#fm .easyui-combobox').combobox ...

  8. Excel表格总是处于只读状态怎么解决?

    如果Excel表格设置了"只读模式",每次打开表格都会弹出对话框,提示"输入密码以获取写权限,或以只读方式打开".这种模式下如何编辑Excel表格,又如何去除呢 ...

  9. css统一将页面input,select,textarea元素改为不可编辑(只读状态)

    我竟然开始一个一个去加readonly和disabled $("textarea[name='realCodeExpression']").val(sourceExpression ...

最新文章

  1. dataframe 拆分 分裂
  2. BZOJ1058 [ZJOI2007]报表统计 set
  3. Rift.io基于OSM发布首个商用MANO软件
  4. mybaits十七:使用foreach标签
  5. 【译】Why Wayland on Android is a hard problem
  6. 不飘了,让图像识别算法快速产业落地 别再实验了,让你的图像识别算法赶紧上线!...
  7. ServiceStack.Ormlit 事务
  8. Qt4_实现Edit菜单
  9. python程序中结束while循环的两种方法是_Python中while循环
  10. linux查找超过一定时间的文件,并批量删除
  11. 红番茄(VS2017)两个注意点
  12. gentoo 修改键盘映射
  13. JS校验银行卡号以及通过银行卡号自动带出所属银行信息
  14. Gentoo Linux 快速安装记录
  15. 树莓派系统安装和环境配置
  16. FileProvider Android7.0 (文件共享,使用系统播放器打开视频等等)
  17. 不聊奶茶妹,咱就聊聊京东2016年校招那些事儿
  18. 你明明是我师父,却偏要做我女朋友
  19. 【Vue如何让v-show也有动画效果】
  20. dialer(dialer接口是什么意思)

热门文章

  1. linux局域网内根据ip查询主机名
  2. 北大计算机学院 教授 湖南人,北大湘籍教授邹恒甫简历
  3. 三维数组设置索引_10-Unity入门学习之C#基础9「数组」
  4. 核密度估计python_非参数估计:核密度估计KDE
  5. 联想笔记本电脑无法在编码中直接使用Home和End快捷键需要+fn解决方案
  6. 中国工科计算机专业,中国最受欢迎的4个工科专业,第1名有些意外,第3名副其实...
  7. jquery function_前端基础进阶(十三)详细图解jQuery扩展jQuery插件
  8. Java使用Proxy和CGLib实现动态代理
  9. 【小白学习PyTorch教程】六、基于CIFAR-10 数据集,使用PyTorch 从头开始​​构建图像分类模型
  10. memoryerror: Unable to allocate array with shape (60000, 28, 28) and data ty