在线QQ客服:1922638
专业的SQL Server、MySQL数据库同步软件
在JD道家订单中心系统业务中,无论是外部商人的订单生产还是内部上游和下游系统的依存关系,订单查询调用的数量都非常大,从而导致阅读量增加和写更少的订单数据。
我们将订单数据存储在MySQL中,但是显然不建议仅通过DB支持大量查询。同时,MySQL支持对某些复杂的查询不够友好,因此订单中心系统使用Elasticsearch承载订单查询的主要压力。
如果您对学习Java有任何疑问(学习方法,学习效率,如何找到工作),请随时与我联系。这是我的Java交流学习小组:934623944。每个人交流问题,互相帮助,这里有很好的学习教程和开发工具。备注:CSDN
Elasticsearch是功能强大的分布式搜索引擎,支持近实时存储和搜索数据。它在京东道教秩序系统中发挥着巨大作用。目前,订购中心的ES集群每天的存储容量达到10亿个文档。平均查询量达到5亿。
近年来,随着JD Daojia业务的快速发展,订单中心的ES安装计划也在不断发展。到目前为止,ES群集架设已成为一组实时的相互备份解决方案,这保证了ES群集读写的稳定性。这是此过程的简要介绍以及该过程中遇到的一些问题。
ES集群体系结构的演变
1.初始阶段
订单中心的ES初始阶段就像一张白纸,基本上没有安装方案。群集的默认配置中保留了许多配置。整个集群都部署在该组的弹性云上,ES集群的节点和机器部署相对混乱。同时,根据集群维度,ES集群将有一个问题点,即显然不允许用于订单中心业务。
2.集群隔离阶段
与许多企业一样,ES群集使用混合分发方法。但是,由于订购中心的ES存储在线订购数据,因此,有时混合的群集会占用大量系统资源,从而导致整个订购中心的ES服务异常。
显然,任何影响订单查询稳定性的情况都是不能容忍的,因此对于这种情况,首先,将订单中心ES所在的弹性云移出系统资源较高的那些集群节点抢占,ES群集状态略有改善。但是,随着群集数据的不断增加,弹性云配置无法满足ES群集的需要,为了实现完全物理隔离,订单中心的ES中心仅部署在高配置的物理计算机上,并且ES群集性能已得到改善。
3.节点复制调整阶段
ES的性能与硬件资源有很大关系。当ES群集分别部署在物理机上时,群集内的节点不会独占整个物理机的资源。当群集运行时,同一物理计算机上的节点仍将存在资源抢占的问题。因此,在这种情况下,为了允许单个ES节点使用最大程度的计算机资源,每个ES节点都部署在单独的物理计算机上。
但是,问题又来了,如果单个节点有瓶颈怎么办?我们应该如何再次优化?
ES查询的原理。当请求命中特定数量的片段时,如果未指定指定片段类型的查询(Preference参数),则请求将被加载到相应片段编号的每个节点上。群集的默认副本配置是一个主副本和一个副副本。鉴于这种情况,我们考虑了扩展副本的方法,从默认的一对主机到一对主副本,同时添加了相应的物理机。
订单中心ES集群的估计
如图所示,整个安装方法使用VIP来平衡外部请求的负载:
整个集群具有一组主要碎片和两组辅助碎片(一个主要碎片和两个辅助碎片)。从网关节点转发的请求将在到达数据节点之前通过轮询进行平衡。群集添加一组副本并扩展计算机的方式增加了群集吞吐量,从而提高了整个群集的查询性能。
下图是订单中心ES集群每个阶段性能的示意图,直观地显示了优化的每个阶段之后ES集群性能的显着提高:
当然,分片的数量和分片副本的数量不是最好。在这一阶段,我们进一步探索了适当数量的碎片的选择。分片的数量可以理解为MySQL中的子数据库子表,当前订单中心的ES查询主要分为两类:单ID查询和分页查询。
分片数量越大,集群的水平扩展越大。根据分片路由的单ID查询吞吐量也可以大大提高,但聚合的页面查询性能将降低;分片数量越小,水平簇的扩展规模也越小,单个ID的查询性能也会降低,但分页查询的性能将会提高。
因此,如何在分片数量和现有查询业务之间取得平衡,我们做了很多次调整压力测试的工作,最后选择了具有更好集群性能的分片数量。
4.主从集群调整阶段
至此,订单中心的ES集群已初具规模,但是由于订单中心业务的高及时性要求和对ES查询稳定性的要求,如果集群中有例外情况,查询服务将受到影响,从而影响整个订单生产过程。显然,这种异常情况是致命的,因此为了处理这种情况,我们最初的假设是添加一个备用群集。当主群集异常时,查询流量可以实时降级到备用群集。
应该如何构建备用集群?如何在主站和从站之间同步数据?备用群集应存储哪种数据?
考虑到ES集群暂时还没有一个好的主从解决方案,同时,为了更好地控制ES数据的写入,我们使用双重写入业务方法来设置主-备用群集。每次业务操作需要写入ES数据时,都会同步写入主集群数据,然后异步写入备用集群数据。同时,由于ES查询的大部分流量来自过去几天的订单,并且订单中心的数据库数据具有归档机制,因此将在指定天数之前关闭的订单转移到历史订单数据库。
因此,删除备用群集文档的逻辑被添加到归档机制中,以使存储在新建备用群集中的订单数据与订单中心在线数据库中的数据量保持一致。同时,ZK用于在查询服务中进行流控制切换,以确保查询流量可以实时降级到备用群集。到此,订单中心的主从集群完成,ES查询服务的稳定性大大提高。
5.如今:实时相互备用双群集阶段
在
期间,由于主群集的ES版本低于1.7,并且ES的稳定版本已迭代到6.x,因此新版本的ES不仅具有出色的性能优化,而且还提供了一些功能。新的和有用的功能。因此,我们将版本从主1.7直接升级到了6.x。
集群升级过程繁琐且漫长。它不仅需要确保在线服务不会产生影响,进行平滑且无意识的升级,而且还因为ES群集不支持跨版本将数据从1.7迁移到6.x,它们还需要重建索引以升级。主群集,具体的升级过程在此不再赘述。
主集群升级后,不可避免地将不可用,但是订购中心的ES查询服务不允许这样做。因此,在升级阶段,备用群集临时充当主要群集,以支持所有联机ES查询,并确保升级过程不会影响正常的联机服务。同时,对于在线业务,我们重新定义了两个集群并重新定义了进行的在线查询流量。
备份群集最近几天在线存储热数据。数据大小比主集群小得多,后者大约是主集群中文档数量的十分之一。集群数据量很小。在相同的集群部署规模下,备用集群的性能要优于主集群。
但是,在实际的联机场景中,大多数联机查询流量也来自热点数据,因此使用备用群集来承载这些热点数据的查询,并且备用群集已逐渐演变为热点数据群集。先前的主群集存储了全部数据,并使用此群集来支持查询流量的其余一小部分。该部分查询主要用于特殊场景查询,这些特殊场景查询需要在订单中心系统中搜索完整的订单和内部查询等,而主集群也逐渐演变为冷数据集群。
同时,备用集群将一键降级功能添加到主集群。两个集群的状态同样重要,但是都可以降级到另一个集群。双重写入策略也按以下方式进行了优化:假设有一个AB群集,正常同步模式写入主群集(A群集),异步模式写入备用群集(B群集)。当A集群中发生异常时,将B集群(主)同步写入,而将A集群(备用)异步写入。
ES订单数据同步方案
MySQL数据已同步到ES。总体摘要可以分为两种方案:
解决方案1:监视MySQL的Binlog,分析Binlog并将数据同步到ES群集。
选项2:直接通过ES API将数据写入ES集群。
考虑到订单系统的ES服务的业务特殊性,订单数据的实时性很高。显然,监视Binlog的方法等效于异步同步,这可能会导致更大的延迟。计划1与计划2基本相似,但是引入了新系统,并且维护成本也增加了。因此,订单中心ES采用直接通过ES API写入订单数据的方法。该方法简单灵活,可以很好地满足订单中心数据同步到ES的需求。
由于ES订单数据的同步已写入企业中,因此当新文档或更新文档中发生异常时,重试将不可避免地影响企业正常运营的响应时间。
因此,每个业务操作仅更新一次ES。如果发生错误或异常,则将修复任务插入数据库中。辅助任务将实时扫描这些数据,并根据数据库订单数据再次更新ES数据。通过这种补偿机制,可以确保ES数据和数据库订单数据的最终一致性。
遇到一些凹坑
如果您对学习Java有任何疑问(学习方法,学习效率,如何找到工作),请随时与我联系。这是我的Java交流学习小组:934623944。每个人都进行了大量交流,互相帮助,该小组的Tutorials和development tools中有很好的学习。备注:CSDN
1.对实时性要求很高的查询进入数据库
了解ES编写机制的学生可能知道,新文档将被收集到索引缓冲区中,然后写入文件系统缓存中,可以像对待文件系统缓存中的其他文件一样对待它们。 。
但是,默认情况下,从索引缓冲区到文件系统缓存(即,刷新操作)的文档每秒钟自动刷新一次,因此这就是为什么我们说ES接近实时搜索,而不是实时搜索:的文档不是立即可见的,但是搜索将在一秒钟内变为可见。
当前的订单系统ES使用默认的Refresh配置,因此对于那些具有高实时订单数据的企业,直接查询数据库以确保数据的准确性。
2.避免进行深度分页查询
ES群集的分页查询支持from和size参数。查询时,每个分片必须构造一个长度为+大小的优先级队列,然后将其传递回网关节点。网关节点对这些优先级队列进行排序查找正确大小的文档。
假设在具有6个主分片的索引中,from为10000,大小为10,则每个分片必须产生10010个结果,并且在网关节点上聚合60060个结果,最后找到10个满足要求的文档。
可以看出,当from足够大时,即使没有发生OOM,也会影响CPU和带宽等,从而影响整个集群的性能。因此,您应该避免进行深度分页查询,并尽量不要使用它们。
3,FieldData和Doc值
FieldData
在线查询有时会超时。通过调试查询语句,确定它与订单有关。排序使用es1.x版本中的FieldData结构。 FieldData占用JVM堆内存。 JVM内存有限。为FieldData缓存设置了阈值。
如果没有足够的空间,请使用最长的未使用(LRU)算法删除FieldData并同时加载新的FieldData缓存。加载过程需要系统资源并消耗大量时间。因此,该查询的响应时间猛增,甚至影响了整个集群的性能。为了解决此问题,解决方案是采用文档值。
文档值
Doc Values是一个列式数据存储结构,与FieldData非常相似,但是其存储位置在Lucene文件中,即不会占用JVM Heap。随着ES版本的迭代,Doc Values比FieldData更稳定,并且Doc Values是2.x中的默认设置。
摘要
体系结构的快速迭代源于业务的快速发展。正是由于近年来家庭业务的飞速发展,订购中心的架构也得到了不断的优化和升级。架构解决方案不是最好的,只有最合适的。我相信,几年后,定单中心的体系结构将是另一种外观,但是具有更大的吞吐量,更好的性能和更高的稳定性,它将成为定单中心系统。永远追求。
如果您对学习Java有任何疑问(学习方法,学习效率,如何找到工作),请随时与我联系。这是我的Java交流学习小组:934623944。每个人都进行了大量交流,互相帮助,该小组的Tutorials和development tools中有很好的学习。备注:CSDN