基于段文件的主从复制
概述
主从复制模式
- Elasticsearch的主从复制模式,是基于“文档复制”(document replication):当有增删改文档操作时,操作请求会先转发到主分片(primary shard),主分片在其本地构建索引,然后把这个操作请求转发给各副本分片(replica shard)所在节点,每个节点分别构建各自的索引数据。
- 百度云Elasticsearch提供一种基于“段复制”(segment replication)的主从同步机制:只有主分片会执行构建索引数据的过程,构建完成后,把新增的索引数据直接复制给各个副本分片。由于Elasticsearch的索引数据底层是lucene的段(segment)文件,因此这种数据复制模式被称为“段复制”。
- 您可根据使用需求,在创建新索引时选择主从复制模式为“文档复制”或“段复制”。
优势
- “文档复制”每个副本所在节点各自构建索引,因此集群整体的cpu开销更大。相比而言,“段复制”会节省这部分cpu压力,从而增加集群的写入吞吐量。不过,“段复制”也会加大集群内部的网络通信压力,以及搜索滞后性。
- 详细对比数据可参考本页末的性能测试。
适用场景
- 写入QPS较大、CPU使用率较高的集群。
- 业务对搜索滞后性不敏感。典型使用场景为日志检索。
使用方式
创建基于段复制的索引
主从复制模式可基于集群粒度或索引粒度来配置。配置只影响新创建的索引,且索引一旦创建后,该索引的复制模式不能再修改。
配置项 | 类型 | 说明 | |
---|---|---|---|
集群粒度 | cluster.indices.replication.strategy | String | 取值"DOCUMENT"或"SEGMENT"(区分大小写),默认值为"DOCUMENT" |
索引粒度 | index.replication.type | String | 取值"DOCUMENT"或"SEGMENT"(区分大小写),默认值为"DOCUMENT" |
- 集群粒度设置使用示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.indices.replication.strategy": "SEGMENT"
}
}
此后新创建的索引,如果不显式指定索引粒度的复制模式,则以集群粒度的配置为准。
- 索引粒度设置使用示例:
PUT /my-index1
{
"settings": {
"index.replication.type": "SEGMENT"
}
}
查看段复制的执行状态
您可查看开启了段复制的索引的执行状态,并可以指定索引:
GET _cat/segment_replication?v
GET _cat/segment_replication/{index}?v
请求参数(可选):
参数名 | 类型 | 说明 |
---|---|---|
shards | String | 指定要查看的shard id列表,如"0,1,2"。默认不填,即查看全部shard。 |
active_only | Boolean | 只查看正在执行段复制的shard。默认false。 |
响应结果说明:
参数名 | 说明 |
---|---|
shardId | shard id |
target_node | 复制目标节点名 |
target_host | 复制目标节点ip |
checkpoints_behind | 副本分片落后主分片的checkpoint数(一个checkpoint对应一个lucene段) |
bytes_behind | 副本分片落后主分片的字节数 |
current_lag | 自主分片刷新(但目前副本尚未同步)到当前的时间 |
last_completed_lag | 上一次主从段复制过程的执行耗时 |
rejected_requests | 拒绝请求数 |
相关优化项
如果启用了“段复制”模式,推荐您了解以下的集群粒度设置,可能会帮助您更好地使用集群。
依据primary数量进行shard分配
Elasticsearch默认的shard分配策略,是使各数据节点的shard数量趋于相同,但不区分primary shard和replica shard。
而如果您开启了段复制功能,且集群内全部索引或绝大部分索引都是基于段复制的,那么仅primary shard有较大的写入压力,因此我们提供了一种根据primary shard数量分配的策略配置:
配置项 | 类型 | 说明 |
---|---|---|
cluster.routing.allocation.balance.prefer_primary | Boolean | 默认值false。如果设置为true,新分配shard的策略会尽量使得各节点的primary shard数量均匀。 |
不过,这个设置只影响新建索引时的shard分配策略。如果开启设置前,所有shard已经被分配均衡,不会因为primary shard的分布不均衡而触发重分配。在其它场景下,比如故障恢复中,该设置也不会影响shard的重分配。
背压机制
我们提供一种分片级背压机制:当副本分片落后于主分片超过一定阈值时,可以动态地拒绝对这个分片的写入请求,直到下降到阈值以下时,又可以恢复写入。如果开启集群的段复制背压机制,则所有段复制模式的索引都会启用背压机制。
配置项如下:
配置项 | 类型 | 说明 |
---|---|---|
segrep.pressure.enabled | Boolean | 集群背压机制的开关。默认值true。 |
segrep.pressure.time.limit | Time Unit | 副本分片从主分片复制所等待的最长时间。默认值5分钟。 |
segrep.pressure.checkpoint.limit | Integer | 副本分片落后于主分片的checkpoint(一个checkpoint对应一个lucene段)的最大数量。默认为4。 |
segrep.pressure.replica.stale.limit | Float | 陈旧副本的比例阈值。当一个副本的"segrep.pressure.time.limit"和"segrep.pressure.checkpoint.limit"两者都达到了阈值,则认为这个副本为“陈旧的”(stale)。当一个分片的各个副本中,陈旧比例达到阈值,则这个分片开始拒绝写入。默认值0.5,即50%。 |
拷贝限速
节点间的段复制过程中,可能存在网络带宽占用较大的问题,默认开启一定的速度限制。而如果您需要尽可能降低主从复制的延迟,可以提高限速阈值,或取消限速。
配置项 | 类型 | 说明 |
---|---|---|
indices.replication.max_bytes_per_sec | String | 每个节点的段复制传输速度限制。默认值"200mb"。如果置为"0mb"则不限速。 |
内核版本要求
Elasticsearch版本7.10.2,内核版本1.7.0及以上。
性能测试
测试集群包括5个es数据节点(bes.g3.c8m32),机型详细规格如下:
配置项 | 类型 |
---|---|
核数 | 8 |
内存 | 32GB |
磁盘类型 | 增强型ssd pl1 |
磁盘容量 | 512GB |
网卡带宽 | 3Gbps |
使用esrally测试工具,数据集为nyc_taxis,每组测试写入8000万条数据(单shard存储占用约16GB)。写入时,每bulk请求10000条文档,并发数为10。
测试结果如下:
primary | replica | err-rate(%) | 文档复制mean throughput(docs/s) | 段复制mean throughput(docs/s) | Percent difference | 文档复制mean service time(ms) | 段复制mean service time(ms) | Percent difference |
---|---|---|---|---|---|---|---|---|
5 | 1 | 0 | 219864.67 | 315401.21 | 43.45% | 496.78 | 339.61 | -31.64% |
10 | 1 | 0 | 251130.60 | 321112.98 | 27.87% | 437.10 | 330.37 | -24.42% |
20 | 1 | 0 | 247969.20 | 326191.10 | 31.55% | 446.63 | 318.40 | -28.71% |
40 | 1 | 0 | 252686.17 | 329312.61 | 30.32% | 417.75 | 306.47 | -26.64% |
结论:
在上述集群配置条件下,与文档复制相比,段复制可以明显提升集群写入性能,写入吞吐量可提升约30%。