OpenSearch Segment Replication 初体验

1 Data Replication 简介

作为一个分布式数据系统,Elasticsearch/OpenSearch 也有主副本( Primary Shard )和副本( Replica Shard )的概念。

Replica 是 Primary 的 Clone ( 复制体 ),这样就可以实现系统的高可用,具备容灾能力。

Replica 从 Primary 复制数据的过程被成为数据复制( Data Replication ),Data Replication 的核心考量指标是 Replica 和 Primary 的延迟( Lag )大小,如果 Lag 一直为0,那么就是实时复制,可靠性最高。

Data Replication 的方案有很多,接下来主要介绍基于文档的复制方案( Document Replication ) 和基于文件的复制方案 ( Segment Replication )。

1.1 Document Replication

Elasticsearch/OpenSearch 目前采用的是基于文档的复制方案,整个过程如下图所示:

image.png
  1. Client 发送写请求到 Primary Shard Node
  2. Primary Shard Node 将相关文档先写入本地的 translog,按需进行 refresh
  3. 上述步骤执行成功后,Primary Shard Node 转发写请求到 Replica Shard Nodes,此处转发的内容是实际的文档
  4. Replica Shard Node 接收到写请求后,先写入本地的 translog,按需进行 refresh,返回 Primary Shard Node 执行成功
  5. Primary Shard Node 返回 Client 写成功。
  6. 后续 Primary Shard Node 和 Replica Shard Node 会按照各自的配置独立进行 refresh 行为,生成各自的 segment 文件。

这里要注意的一点是:Primary Shard 和 Replica Shard 的 refresh 是独立的任务执行时机和时间会有所差异,这也会导致两边实际生成和使用的 segment 文件有差异。

以上便是 Document Replication 的简易流程,对完整流程感兴趣的,可以通过下面的连接查看更详细的介绍。

1.2 Segment Replication

elasticsearch 数据写入最耗时的部分是生成 segment 文件的过程,因为这里涉及到分词、字典生成等等步骤,需要很多 CPU 和 Memory 资源。

而 Document Replication 方案需要在 Primary Node 和 Replica Nodes 上都执行 segment 文件的生成步骤,但是在 Replica Nodes 上的执行实际是一次浪费,如果可以避免这次运算,将节省不少 CPU 和 Memory 资源。

解决的方法也很简单,等 Primary Node 运行完毕后,直接将生成的 segment 文件复制到 Replica Nodes 就好了。这种方案就是 Segment Replication。

Segment Replication 的大致流程如下图所示:

image.png
  1. Client 发送写请求到 Primary Shard Node
  2. Primary Shard Node 将相关文档先写入本地的 translog,按需和相关配置进行 refresh,此处不是一定触发 refresh
  3. 上述步骤执行成功后,Primary Shard Node 转发写请求到 Replica Shard Nodes,此处转发的内容是实际的文档
  4. Replica Shard Node 接收到写请求后,写入本地的 translog,然后返回 Primary Shard Node 执行成功
  5. Primary Shard Node 返回 Client 写成功。
  6. Primary Shard Node 在触发 refresh 后,会通知 Replica Shard Nodes 同步新的 segment 文件。
  7. Replica Shard Nodes 会对比本地和 Primary Shard Node 上的 segment 文件列表差异,然后请求同步本地缺失和发生变更的 segment 文件。
  8. Primary Shard Node 根据 Replica Shard Nodes 的相关请求完成 segment 文件的发送
  9. Replica Shard Nodes 在完整接收 segment 文件后,刷新 Lucene 的 DirectoryReader 载入最新的文件,使新文档可以被查询

这里和 Document Replication 最大的不同是 Replica Shard Nodes 不会在独立生成 segment 文件,而是直接从 Primary Shard Node 同步,本地的 translog 只是为了实现数据的可靠性,在 segment 文件同步过来后,就可以删除。

以上便是 Segment Replication 的简易流程,对完整流程感兴趣的,可以通过下面的连接查看更详细的介绍。

2 Segment Replication 初体验

OpenSearch 在 2.3 版本中发布了实验版本的 Segment Replication 功能,接下来就让我们一起体验一下吧~

2.1 准备 docker 环境和相关文件

本次体验基于 docker-compose 来执行,如下为相关内容(docker-compose.yml):

version: '3'
services:
  opensearch-node1:
    image: opensearchproject/opensearch:2.3.0
    container_name: os23-node1
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node1
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
      - plugins.security.disabled=true
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m -Dopensearch.experimental.feature.replication_type.enabled=true" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems
        hard: 65536
    volumes:
      - ./os23data1:/usr/share/opensearch/data
    ports:
      - 9200:9200
      - 9600:9600 # required for Performance Analyzer
    networks:
      - opensearch-net
  opensearch-node2:
    image: opensearchproject/opensearch:2.3.0
    container_name: os23-node2
    environment:
      - cluster.name=opensearch-cluster
      - node.name=opensearch-node2
      - discovery.seed_hosts=opensearch-node1,opensearch-node2
      - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
      - bootstrap.memory_lock=true
      - plugins.security.disabled=true
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m -Dopensearch.experimental.feature.replication_type.enabled=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./os23data2:/usr/share/opensearch/data
    networks:
      - opensearch-net
  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:2.3.0
    container_name: os23-dashboards
    ports:
      - 5601:5601
    expose:
      - "5601"
    environment:
      OPENSEARCH_HOSTS: '["http://opensearch-node1:9200","http://opensearch-node2:9200"]'
      DISABLE_SECURITY_DASHBOARDS_PLUGIN: "true"
    networks:
      - opensearch-net

networks:
  opensearch-net:

简单说明如下:

  • 为了演示方便,关闭了安全特性
  • 要在 OPENSEARCH_JAVA_OPTS 中添加 -Dopensearch.experimental.feature.replication_type.enabled=true 才能开启segment replication 功能

2.2 运行 OpenSearch 集群

执行如下命令运行 OpenSearch Cluster:

docker-compose -f docker-compose.yml up

运行成功后,可以访问 http://127.0.0.1:5601 打开 Dashboards 界面,进入 Dev Tools 中执行后续的操作

2.3 测试 Segment Replication

测试思路如下:

  1. 创建两个 index,一个默认配置,一个启用 segment replication,主分片数为1,副本数为1
  2. 向两个 index 中插入若干条数据
  3. 比较两个 index 中 segment file 的数量和大小

相关命令如下:

PUT /test-rep-by-doc
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  }
}

GET test-rep-by-doc/_settings

POST test-rep-by-doc/_doc
{
  "name": "rep by doc"
}

GET _cat/shards/test-rep-by-doc?v

GET _cat/segments/test-rep-by-doc?v&h=index,shard,prirep,segment,generation,docs.count,docs.deleted,size&s=index,segment,prirep


PUT /test-rep-by-seg
{
  "settings": {
    "index": {
      "replication.type": "SEGMENT",
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  }
}


GET test-rep-by-seg/_settings

POST test-rep-by-seg/_doc
{
  "name": "rep by seg"
}

GET _cat/shards/test-rep-by-seg

GET _cat/segments/test-rep-by-seg?v&h=index,shard,prirep,segment,generation,docs.count,docs.deleted,size&s=index,segment,prirep

插入文档后,通过 _cat/segments 可以得到 segment file 列表,然后通过 size 一列可以对比 segment 文件大小。

如下是默认基于文档复制的结果:

index           shard prirep segment generation docs.count docs.deleted  size
test-rep-by-doc 0     p      _0               0          2            0 3.7kb
test-rep-by-doc 0     r      _0               0          1            0 3.6kb
test-rep-by-doc 0     p      _1               1          2            0 3.7kb
test-rep-by-doc 0     r      _1               1          3            0 3.8kb
test-rep-by-doc 0     p      _2               2          1            0 3.6kb
test-rep-by-doc 0     r      _2               2          3            0 3.8kb
test-rep-by-doc 0     p      _3               3          6            0 3.9kb
test-rep-by-doc 0     r      _3               3          6            0 3.9kb
test-rep-by-doc 0     p      _4               4          5            0 3.9kb
test-rep-by-doc 0     r      _4               4          6            0 3.9kb
test-rep-by-doc 0     p      _5               5          6            0 3.9kb
test-rep-by-doc 0     r      _5               5          6            0 3.9kb
test-rep-by-doc 0     p      _6               6          4            0 3.8kb
test-rep-by-doc 0     r      _6               6          1            0 3.6kb

从中可以看到,虽然 Primary Shard 和 Replica Shard 的 segment 数相同,但是 size 大小是不同的,这也说明其底层的 segment 文件是独立管理的。

如下是基于 Segment 复制的结果:

index           shard prirep segment generation docs.count docs.deleted  size
test-rep-by-seg 0     p      _0               0          2            0 3.7kb
test-rep-by-seg 0     r      _0               0          2            0 3.7kb
test-rep-by-seg 0     p      _1               1          7            0   4kb
test-rep-by-seg 0     r      _1               1          7            0   4kb
test-rep-by-seg 0     p      _2               2          5            0 3.9kb
test-rep-by-seg 0     r      _2               2          5            0 3.9kb

从中可以看到 Primary Shard 和 Replica Shard 的 segment 完全一致。

除此之外也可以从磁盘文件中对比,同样可以得出相同的结论:Segment Replication 是基于文件的数据复制方案,Primary 和 Replica 的 segment 文件列表完全相同。

3 总结

根据 OpenSearch 社区的初步测试,Segment Replication 相较于 Document Replication 的性能结果如下:

  • 在 Replica Nodes 上,CPU 和 Memory 资源减少 40%~50%
  • 写入性能方面,整体吞吐量提升约 50%,P99 延迟下降了 20% 左右

这个测试结果还是很诱人的,但 Segment Replication 也有其自身的局限,下面简单列几点( 不一定准确 ):

  • Segment Replication 对于网络带宽资源要求更高,目前测试中发现有近1倍的增长,需要更合理的分配 Primary Shard 到不同的 Node 上,以分散网络带宽压力
  • Segment Replication 可能会由于文件传输的延迟而导致 Replica Shard 上可搜索的文档短时间内与 Primary Shard 不一致
  • Replica Shard 升级为 Primary Shard 的时间可能会因为重放 translog 文件而变长,导致 Cluster 不稳定

友情提示下,由于该特性目前还是实验阶段,还不具备上生产环境的能力,大家可以持续关注~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 一、ES基本概念 1.1 索引(Index) 一个索引就是一个拥有几分相似特征的文档的集合。一个索引由一个名字来标...
    CJ21阅读 2,236评论 2 21
  • 1.为什么要使用Elasticsearch? ​ 因为在我们商城中的数据,将来会非常多,所以采用以往的模糊查询,模...
    陈二狗想吃肉阅读 5,478评论 0 12
  • 一,读写底层原理 Elasticsearch写人数据的过程 1)客户端选择一个node发送请求过去,这个node就...
    CoderZS阅读 1,693评论 0 0
  • Cluster:代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于...
    moonhatred阅读 760评论 0 0
  • 简单操作可以直接使用ElasticsearchRespositor接口,复杂的使用ElasticsearchTem...
    一个彩笔程序猿阅读 699评论 0 0