• Elasticsearch:如何部署 Elasticsearch 来满足自己的要求


    在我之前的文章:

    我们涉及到一些分片管理,内存管理已经分片策略的一些知识。在实际的使用中,我们该如何对 Elasticsearch 集群做正确的 sizing。我们到底需要多少内存,多少个 CPU,多少个 shards 等等。在今天的文章中,我总结一些专家的建议,希望对于正确使用 Elasticsearch 提供一些参考的意见。在实际的使用中,可能需要根据自己的使用进行调整。如果你对分片(shard)的概念不是很熟悉的话,请阅读我之前的文章 “Elasticsearch 中的一些重要概念: cluster, node, index, document, shards 及 replica”。

    分片策略

    在最新的 Elasticsearch 的默认部署中,每个创建的索引只是有一个 primary shard。这个是在索引创建的时候定义的。比如我们创建一个索引:

    PUT order

    我们通过如下的命令来获得它的设置:

    GET order/_settings

    上面的命令将返回如下的结果:

    1. {
    2. "order": {
    3. "settings": {
    4. "index": {
    5. "routing": {
    6. "allocation": {
    7. "include": {
    8. "_tier_preference": "data_content"
    9. }
    10. }
    11. },
    12. "number_of_shards": "1",
    13. "provided_name": "order",
    14. "creation_date": "1666584276053",
    15. "number_of_replicas": "1",
    16. "uuid": "tmVY0iDoTnGDuEZRpf_0hA",
    17. "version": {
    18. "created": "8040399"
    19. }
    20. }
    21. }
    22. }
    23. }

    我们可以看到在默认的情况下, number_of_shards 的数值为 1,也即一个 primary shard。同时它的 number_of_replicas 的值为 1,也即一个 replica。你可以在创建索引的时候,指定 number_of_shards 为超过 1 的数值。最多可以达到 1024。比如:

    1. PUT order
    2. {
    3. "settings": {
    4. "number_of_shards": 4,
    5. "number_of_replicas": 2
    6. }
    7. }

    如果你已经创建了索引,那么再重新定义 number_of_shards 时,你需要 reindex 才可以。

    无法在实时索引上修改分片的数量

    索引创建并运行后,分片数量无法更改。 当我们创建索引时,Elasticsearch 默认关联一个分片和一个副本(在版本 7 之前,默认是 5 个分片和 1 个副本)。 虽然设置了分片的数量(很像写在石头上),但可以在索引的生命周期中使用索引设置 API 更改副本的数量。 根据路由算法,文档存放在特定的分片中:

    shard_number = hash(document_id) % number_of_primary_shards

    由于算法直接取决于分片的数量,因此在实时运行期间更改分片数量将修改当前文档的位置并破坏它。 这反过来又会损害倒排索引和检索过程。 不过,有一种方法可以解决这个问题:重新索引(reindex)。 通过重新索引,我们可以根据需要更改分片设置。 有关 reindex 的介绍,请阅读文章 “Elasticsearch: Reindex 接口”。

    我们该如何计算多少个 shard 呢?如上所示,假如我们定义创建的索引 order 含有 4 个 primary shards 及 2 个 replica shards,那么:

    针对这个 order 索引,我们供需要 4 个 primary shards 以及 8 个 replica shards。这样我们供需要 8 + 4 = 12 个 shards。

    如果我们为一个索引分配更多的 primary shards,则意味着:

    • 跟多的并行处理 indexing。当我们向集群同时写入大量数据时,那么有更多的 primary shards 可以同时对写入的文档进行分词处理从而提高写入的速度
    • 对搜索的速度可能稍微有些影响,尽管不是绝对的。这是因为 Elasticsearch 的搜索是一个分布式的,当一个请求发送到一个 coodinating 节点后,它会分发这个搜索到各个节点进行搜索。当每个节点在本地完成了搜索后,它们会把自己的结果一并发送到 coordinating 节点,并进行合并得出最后的结果,比如前十匹配的结果。Primary shard 的数量越多,那么合并的工作会更多。

    在实践中,为了更好的搜索效果,我们建议每个 shard 的大下位于 10 GB 到 50 GB 之间:

    经常被问到的一个常见问题是关于分片的大小。 这里没有万能的。 根据组织当前的数据要求和未来需求,必须进行(尽职调查)规模试验以获得结论性结果。 业界的最佳实践是将单个分片的大小设置为不超过 50 GB。 但我也看到分片的大小达到 400 GB。 事实上,GitHub 的索引分布在 128 个分片中,每个分片 120 GB。 我个人的建议是将它们保持在 25 GB 到 40 GB 之间,同时牢记节点的堆内存。 如果我们知道某个电影索引在某个时候最多可以保存 500 GB 的数据,建议将这些数据分布在 10 到 20 个分片中。为了达到调优,一般可以考虑针对 search 使用案例时,shard 的大小为 25 GB。不要超过 50 GB。

    更大的 shard 大小很难是一个集群在经历失败后恢复过来,这是因为更难把一个 shard 从一个节点移动到另外一个节点,特别是一个节点在进行维护时。

    在调整分片大小时还需要考虑一个参数:堆内存。 众所周知,节点的计算资源是有限的,例如内存和磁盘空间。 每个 Elasticsearch 实例都可以根据可用内存进行调整以使用堆内存。默认情况下,Elasticsearch 使用 1 GB 内存进行实例化,但可以通过编辑安装的 config 目录中的 jvm.options 文件来更改设置。 调整 JVM 的 Xms 和 Xmx 属性以根据您的可用性和需要设置帮助内存。针对每个 GB 的 heap 内存,我们希望对于的 shard 数量是 20,尽管这个在 Elastic Stack 8.3 版本发布后有所改变。详细规则请阅读链接。依据这个原则,假如我们有 30 GB 的 heap 内存,那么我们理想的 shard 数量应该为 600 个。

    这里的要点是分片是保存我们数据的分片,因此我们必须做初步的工作以正确调整大小。 大小取决于索引保存的数据量(包括未来的需求)以及我们可以分配给节点的堆内存量。 在载入数据之前,每个组织都必须制定分片策略。 必须在数据需求和最佳分片数量之间取得平衡。

    分配多少个 shards 及多少个 nodes?

    我们可以参考之前的文章 “Elasticsearch:我的 Elasticsearch 集群中应该有多少个分片?” 做更进一步的阅读。根据一些公司的经验,我们可以简单地做如下的表述:

    Number of shards = (SourceData + Room to Grow) x (1 + 10% Indexing Overhead) / Desired Shard Size

    我们可以根据一下的公式计算出需要多少存储:

    Minimum storage required = SourceData x (1+ Number of Replicas) x 1.45

    在上面,这个系数 1.45 包含 Elasticsearch, 索引以及 Linux kernel 的开销。

    针对一个处理复杂聚合,搜索强求以及高输出,经常更新的集群来说,我们可以通过如下的公式来计算 CPU 以及内存的需求:

    node config = 2 vCPU and 8GB memory for every 100 GB of storage

    重要的是,在设置 Elasticsearch 的节点 JVM heap 大小不要超过 50% 的机器物理内存,并且这个数值不可以超过 32 GB。

    下面,我们以一个简单的例子来展示上面的公式。假设我们有 150 GB 的数据需要索引到 Elasticsearch 集群。假如你这个数据是静态的,并且将来不会有增长,那么我们可以可以计算出 primary shards 的数量:

    Number of primary shards (starting from scratch or no growth) = (150+0) x 1.10 / 25 = 7

    在上面,我们假设每个 shard 的大小为 25 GB。上面的公式给出的结果为 7,也即我们需要有 7 个 primary shards。

    假如,你在未来的一年,可能需要有 150 GB 的大小增长,那么我们可以使用如下的公式来算出 primary shards 的数量:

    Number of primary shards (with 100% growth in a year) = (150+150) x 1.10 /25 = 13

    上面的公式给出的结果约为 13,也即我们需要有 13 个 primary shards。

    这个在实际的使用中非常重要,因为一旦我们定义好 primary shards 的数量,那么我们就不能再改动了,除非我们创建一个新的索引,并使用 reindex 包数据重新写入。

    我们再假设我们有一个比较小的 Elasticsearch 集群,它含有 3 个节点 (master + data)。同时,我们假设我们的每个 shard 有一个 replica。我们通过如下的公式来计算最小的存储空间:

    Minimum storage required = 150 x (1+1) x 1.45 = 435 GB

    上面的公式给出的答案是 435 GB。

    我们通过如下的公式来计算内存的要求:

    Compute and Memory = 435 x (2 vCPU and 8 GB memory)/100 = 9 vCPUs and 35 GB of memory

    根据上面的计算,我们的3个节点,每个需要有 3 vCPUs,12 GB 内存 以及 150 GB 的磁盘存储。

    我们的每个节点含有 12 GB 的内存,我们可以设置 JVM 的 heap 大小为 6GB 。这个相当于每个节点最多含有 120 个 shards。3 个节点总共最多含有 360 个shards。

    如果你需要检测你的配置,你可以使用 Elastic 官方提供的工具 GitHub - elastic/rally: Macrobenchmarking framework for Elasticsearch

  • 相关阅读:
    html中标签的分类
    JSP application 对象
    2021icpc南京站
    bash和sh和./的区别
    学会这招,轻松掌握学校教学质量!
    Hadoop运行模式、本地运行模式(官方WordCount)、完全分布式运行模式(开发重点)、scp、rsync 远程同步工具、xsync集群分发脚本
    蓝桥杯-星期一
    MySQL高级篇——存储过程和函数中的变量
    基于C++的即时通信软件设计
    Redis从入门到放弃(10):分布式锁
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/127405447