Q:有两个人掉到陷阱里了,死的人叫死人,活人叫什么?

Elasticsearch 副本分片恢复请教

Elasticsearch | 作者 chengyang | 发布于2019年11月20日 | 阅读数:2544

Elasticsearch在副本分片恢复时,会优先去选择在有副本的段文件的节点上进行恢复,这样可以避免大量的段文件的拷贝,然而在我的实验环境中副本没有按照预期进行本地恢复。
private static long computeMatchingBytes(TransportNodesListShardStoreMetaData.StoreFilesMetaData primaryStore,
TransportNodesListShardStoreMetaData.StoreFilesMetaData storeFilesMetaData) {
String primarySyncId = primaryStore.syncId();
String replicaSyncId = storeFilesMetaData.syncId();
// see if we have a sync id we can make use of
if (replicaSyncId != null && replicaSyncId.equals(primarySyncId)) {
return Long.MAX_VALUE;
} else {
long sizeMatched = 0;
for (StoreFileMetaData storeFileMetaData : storeFilesMetaData) {
String metaDataFileName = storeFileMetaData.name();
if (primaryStore.fileExists(metaDataFileName) && primaryStore.file(metaDataFileName).isSame(storeFileMetaData)) {
sizeMatched += storeFileMetaData.length();
}
}
return sizeMatched;
}
}
在上述的代码片段中,如果主分片和副本的syncid一致的话,会认为是匹配的,sync_id的一致依赖于对空闲的索引,ES会每隔5min进行一次synced flush,并且可以手动执行_flush/sync来生成一个主副一致的sync_id。
在某些情况下sync_id可能不存在或者发生了变化,ES会去比较主分片和副本分片上的段文件是否一致 ,即`if (primaryStore.fileExists(metaDataFileName) && primaryStore.file(metaDataFileName).isSame(storeFileMetaData))`
而isSame方法是比较了主分片和副本段文件的length、checksum、hash,当三者都一致时才认为一致,如下代码片段所示:
    public boolean isSame(StoreFileMetaData other) {
if (checksum == null || other.checksum == null) {
// we can't tell if either or is null so we return false in this case! this is why we don't use equals for this!
return false;
}
return length == other.length && checksum.equals(other.checksum) && hash.equals(other.hash);
}
在调试过程中发现,同一分片的主分片和副本分片的checksum经常会不一致,那么在sync_id不一致时就很难重用之前的段文件了。
 
我现在有如下的困惑:
1. checksum值在主分片上和副本分片上什么情况下会发生不一致?怎么能让他们一致?
2. 在集群重启前是否可以在停止集群后将主分片下的所有段文件手动拷贝到副本的路径下来避免ES自己拷贝是否可行?有没有相关建议?
已邀请:

envy666

赞同来自:

我记得重启的方法应该是,禁用集群分片分配=》重启节点1=》开启集群分片分配=》禁用集群分片分配=》重启节点2=》开启集群分片分配.。。。。。直到所有节点重启完毕,这样能保证分块不会到处飘,也就避免了数据拷贝

fanmo3yuan

赞同来自:

可以参考这篇文章  https://elasticsearch.cn/article/38

要回复问题请先登录注册