作为一家研究过木筏的公司,汤郑杨(Tong Cheng Yilong)早在14年算法的论文中就已经对其进行了调查。同时,它也与Paxos,Zab和其他算法进行了比较。计数器,任务调度元信息存储和其他方案是试行的。很少参与Java Technology stack。此外,基于ETCD的旧项目需要重建,因为需要自定义的数据结构。原始ETCD无法满足基础数据结构的需求。因此,遵循-up解决多个节点数据的强一致性问题。本文假设读者对筏的概念有深刻的了解,并且一致性一致。它详细介绍了如何在使用过程中遇到的JRAFT旧系统转换和工程问题的内部使用。
首先,后台公司最初存在于系统MDB(元数据数据库)中。编写GO语言是为了管理所有实例元数据信息。元数据的内容是地图。此组件为元数据添加,删除和修改提供了一个接口,并用GO语言编写。搜索数据时,会引入K8S选择器软件包,并使用K8S Selector的分析规则筛选了特定标签的元数据信息。DATA持久性是一种实用且坚固的符合存储的组件,用于存储。关键是元数据的ID,以确保唯一的值是特定的元信息,包括每个标签和相应的值。
该系统的一般体系结构如图1所示:
图1:原始体系结构
这种体系结构的缺点:
可以发现对上述问题的分析是,将ETCD用作强大的一致存储,但是ETCD是基于KV的组件,并且分析组件MDB和ETCD是分开的。当需要保证数据时,必须使用最新数据将最新数据获取到最新数据。在本地操作。基于KV等,ETCD必须获取ETCD的完整数据并将其拉到当地在这样做之前。
如果有一个组件可以提供强大的一致存储能力,并且可以直接分析K8S选择器的规则,则存储数据结构和元数据信息更加亲密,则可以直接删除中间的MDB层。该组件是通过此组件。LET分析相应的CRUD规则,并在分析后直接查询规则,因此可以直接解决上述问题。
其次,转换基于上述问题。我们正在准备开发一个坚固的存储组件,该组件可以分析我们自己的K8S选择器规则并将数据保存在我们自己的本地中。因为个人对Java语言有更多了解,并且在使用NACOS时,我也有一定的一定对沙发裁判的理解。最后,我选择了沙发jraft来构建强大的一致存储组件并将其命名为MDB商店。
主要转换点:转换后的体系结构如图2所示:
图2:重建体系结构
转换后,删除MDB以允许用户直接与MDB商店进行通信。中间通信较少,并且速度提高了访问效率。mdb和etcd也已删除,减少了整个系统的组件,并降低了操作和维护成本。
第三,Sofa-Jraft 3.1的特定用法将写作操作转换为SOFA-JRAFT中的RAFT日志。编程模型与一般的Spring MVC编程模式不同。在Spring MVC中,请求到达后端,通常是控制器 - > Service-> processor.controller负责资源映射的几层。此HTTP请求,然后通过控制器调用特定的服务方法。在服务层中,处理和转换参数的某些处理和转换,然后将处理器层发送到请求。
一般逻辑如图3所示
图3:通常的编程模型
在SOFA-JRAFT中,必须通过状态计算机执行所有写作操作(读取操作不需要通过状态计算机)。业务处理。task包含两个需要遵循的属性,一个是完成的,另一个是数据。例如,在DINE的回调逻辑中,对客户端的响应齐平。DATA是RAFT日志中的特定数据,例如在数据中执行的命令。DATA将包括此操作的类型(插入),并且特定此操作的数据。
一般逻辑如图4所示
图-4:沙发 - 杰拉夫编程模型
所有操作都将其抽象成实体操作。在服务层上,根据业务将参数转换为不同的操作,然后将操作序列化为任务实体,然后由Node提交。您可以将任务视为RAFT日志。一旦将木筏日志通过一半的机器提交。状态机将应用RAFT日志,并在应用程序完成后,将触发“完成的回调”。
3.2状态计算机的实现3.3使用读数读数的阅读操作根据筏纸读取。通常,读取操作只能由领导者处理,以便可以读取的数据可以保持一致。在这种情况下,没有办法增加阅读请求的吞吐量。提供可以在追随者中阅读的读取索引读取,并可以确保追随者阅读的结果与Leading in Leaders中的阅读结果一致。阅读索引阅读,您可以在pingcap https中参考此博客https https://pingcap.com/zh/blog/lease-阅读。
com.alipay.sofa.jraft.node#readIndex(final byte [] requestContext,最终readIndExclosure完成)。第一个参数是启动读数读取的上下文,可以在回调中使用。第二个参数是特定的调整逻辑,它需要在运行方法中实现读取逻辑。
并且您需要通过spi.file path/rsources/meta-inf.services/com.alipay.sofa.jraft.rpc.rrpc.raftrpcfactory来指定grpcraftrpcfactory
在这里,您可以定义一个处理器来实现RPCProcessor接口,将处理器注册到RPCServer中,并重复使用相同的RPCServer。
第四,SOFA-JRAFT 4.1读取读数的一些实践返回了太多的数据,导致OOM具有在我们的业务场景中获得完整数据的界面,并通过read-Index读取数据。当对此界面进行压力测试时,发现CPU飙升。经过调查后,由于堆叠的内存已满,因此GC线程一直在起作用。在转储桩内存后,发现这是由于内部使用破坏者的问题。这个问题已由我们解决,也被送回了社区,该社区已在1.3.8版中解决。有关特定问题,请参见第618期。
4.2读数读取响应时间更长。进行测试同学。发现读取接口的最大时间消耗偶尔会运行到500ms,平均响应时间约为100m。重复进行调查和阅读代码后,最终发现此问题与eplection timeout.in Sofa-Jraft有关,选举超时是选举的暂停。一旦超出选举超时,Follwork就没有收到领导者的心跳。将向追随者发送10个心跳。选举,我设置的选举超时仅为5秒,而5s / 10仅为500ms。
因此,进一步分析读取读取的机制。当追随者使用读数读取时,首先要转到领导者获取领导者的当前提交索引,然后您需要等待应用程序索引应用追随者自己的状态机器的索引,以超过从领导者那里获得的提交。然后,索引将调用读数读取。追随者状态机器的应用操作是由领导者的心跳请求驱动的。可以知道筏日志是否提交一半。一旦将某个筏日志提交了一半,领导者将在下一个心跳请求中发送最新信息。Commit索引同步到追随者,并且追随者在将您的状态计算机驱动到Apply Raft log之前,然后收到新的提交索引。心跳请求是选举超时 /10。读数读取的所有响应时间将是选举超时 / 10。
解决方法:基于上述分析,将选举超时的时间调整为1,心跳的频率变为100ms,最大响应时间较低,平均响应时间减少到约4ms。
读取索引可能读取逻辑,如图5所示
图5:读数读取处理逻辑
4.3 READ-INDEX READ的大响应接口未能将请求转发给领导者导致状态机在调查过程中阻止问题,怀疑网络存在问题。维护同学已经掌握了网络以执行TCPDUMP命令并抓住网络。整个集群分为3个机室,并部署了2+2+1模式。1该节点的网络偶尔会波动。当时TCPDUMP执行后4分钟,Read-Index超时开始读取该节点的请求,并且逻辑是,只要读取索引读取为不行,请求已转发到木筏上,木筏接下了筏。
这里有一个接口可以读取所有数据,并且数据量相对较大。当读取索引读取超时时,此请求将转发给Leader Node,拿起Raft Log以读取数据,然后将RAFT日志带到在状态机器中处理它。当时消耗DE分级数据时,消耗1500ms需要时间。状态计算机中筏日志的吞吐量减小。木筏日志将从领导者到追随者复制。也就是说,追随者的状态机还将执行及时1500毫秒的筏日志,但追随者不处理响应。
上述读取的读取逻辑的逻辑。追随者希望执行读取读数。状态机器的应用索引需要赶上领导者的提交索引。状态机处理筏日志吞吐量使Follwer的应用索引更难赶上领导者的提交索引。因此,它被困在恶性圈中。这个大界面通过木筏日志一致转向领导者以读取数据,并且该筏日志处理是非常时间的。最终,状态计算机的应用索引远小于提交索引。
如何解决:将这个大界面的阅读操作更改为快速故障。一旦读数读取的恢复不成功,请求将不会通过筏日志传输到领导者,并将直接返回客户端以进行客户端测试。
4.4当快照操作时,阻塞状态机器会应用筏日志,这会导致响应超时系统在运行客户端时偶尔运行客户端。重复检查后,发现超时的时间点和快照的时间重合。根据读取代码,发现状态机的应用操作默认情况下与快照操作同步,并且快照是更多的时间 - 耗费,结果是客户端请求超时。
如何解决:在快照期间,将快照操作转换为异步操作,在快照时使用副本复制复制内存数据,然后继续对其进行异步处理。在这里应注意的是,在这里,写入副本将消耗2次内存。在这里,您需要确保不引起OOM。不同的方案需要考虑不同的异步快照方法。
4.5 RAFT中存在Raft Log和快照文件,该文件需要文件系统以确保状态SOFA-JRAFT需要保存木筏日志和快照文件。部署容器时,需要使用的筏目录是耐用的。
4.6打开指标并使用kill -s sigusr2在沙发-Jraft中分析问题,是否有一个节点参数,是否打开指标统计指标。我们将其打开并将指示数据输出到单独的日志文件中。档案日志可以在分析问题时提供线索。例如:有时阅读请求的响应时间增加,您可以通过观察索引数据读取索引来分析是否分析线性阅读机制。
将指示器输出到日志文件:
此外,您还可以使用Kill -S Sigusr2 PID将信号量发送到JRAFT过程。在该过程收到信号量之后,它将在该过程的启动目录中生成指示数据文件。从这里我亲自对Node_describe进行更多关注。日志管理器中的log Diskid和AppliedID。前者是在磁盘上写入的筏日志的位置。请注意状态机的吞吐量是否正常。一旦两者大不相同,这意味着状态机是有问题的。
5.随后的演变6.结论以上是在我们公司中使用沙发裁判。如果您有问题,您可以直接找到我的GitHub邮箱来与我通信。谢谢Sofa-Stack.Recpect提供的如此出色的Java框架!!!
作者的参考