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 现在选用的是依据文档的仿制计划,整个过程如下图所示:

Client 发送写恳求到 Primary Shard Node
Primary Shard Node 将相关文档先写入本地的 translog,按需进行 refresh
上述过程履行成功后,Primary Shard Node 转发写恳求到 Replica Shard Nodes,此处转发的内容是实践的文档
Replica Shard Node 接纳到写恳求后,先写入本地的 translog,按需进行 refresh,返回 Primary Shard Node 履行成功
Primary Shard Node 返回 Client 写成功。
后续 Primary Shard Node 和 Replica Shard Node 会依照各自的装备独立进行 refresh 行为,生成各自的 segment 文件。

这儿要注意的一点是:Primary Shard 和 Replica Shard 的 refresh 是独立的使命,履行机遇和时刻会有所差异,这也会导致两边实践生成和使用的 segment 文件有差异。

以上就是 Document Replication 的简易流程,对完好流程感兴趣的,能够经过下面的衔接检查更具体的介绍。

www.elastic.co/guide/…
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 的大致流程如下图所示:

Client 发送写恳求到 Primary Shard Node
Primary Shard Node 将相关文档先写入本地的 translog,按需和相关装备进行 refresh,此处不是必定触发 refresh
上述过程履行成功后,Primary Shard Node 转发写恳求到 Replica Shard Nodes,此处转发的内容是实践的文档
Replica Shard Node 接纳到写恳求后,写入本地的 translog,然后返回 Primary Shard Node 履行成功
Primary Shard Node 返回 Client 写成功。
Primary Shard Node 在触发 refresh 后,会通知 Replica Shard Nodes 同步新的 segment 文件。
Replica Shard Nodes 会比照本地和 Primary Shard Node 上的 segment 文件列表差异,然后恳求同步本地缺失和产生改变的 segment 文件。
Primary Shard Node 依据 Replica Shard Nodes 的相关恳求完成 segment 文件的发送
Replica Shard Nodes 在完好接纳 segment 文件后,改写 Lucene 的 DirectoryReader 载入最新的文件,使新文档能够被查询

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

以上就是 Segment Replication 的简易流程,对完好流程感兴趣的,能够经过下面的衔接检查更具体的介绍。

github.com/opensearch…
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

测验思路如下:

创建两个 index,一个默许装备,一个启用 segment replication,主分片数为1,副本数为1
向两个 index 中刺进若干条数据
比较两个 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 不稳定

友谊提示下,因为该特性现在仍是试验阶段,还不具有上出产环境的才干,我们能够持续关注~

来源: OpenSearch Segment Replication 初体会