面试题答案
一键面试确保文档覆盖强一致性的机制设计
- 使用同步复制:
- ElasticSearch 支持同步复制,通过设置
replication
为sync
,可以确保主分片在将文档变更复制到所有同步副本分片后才确认成功。这保证了在主分片确认写入成功时,所有同步副本都有相同的数据,从而保证强一致性。
- ElasticSearch 支持同步复制,通过设置
- 版本控制:
- ElasticSearch 为每个文档分配一个版本号。每次文档更新时,版本号递增。客户端在更新文档时,可以指定要更新的版本号。如果当前文档版本与指定版本不匹配,更新操作将失败。这可以防止并发更新导致的数据覆盖问题。
- 使用分布式锁(可选):
- 对于一些需要更高一致性保证的场景,可以借助分布式锁,如使用 Redisson 等库实现分布式锁。在更新文档前获取锁,更新完成后释放锁,保证同一时间只有一个节点能对文档进行更新操作。
核心配置
- 同步复制配置:
- 在 ElasticSearch 的索引创建请求中设置
replication
参数:
{ "settings": { "index": { "number_of_shards": 1, "number_of_replicas": 1, "index.write.wait_for_active_shards": "all", "index.translog.durability": "request" } } }
index.write.wait_for_active_shards
: 设置为all
确保主分片等待所有副本分片确认写入成功。index.translog.durability
: 设置为request
保证每个写入请求都持久化到 translog,提高数据可靠性。
- 在 ElasticSearch 的索引创建请求中设置
Java API 代码示例
- 使用 Java High - Level REST Client 进行文档更新并保证一致性:
import org.apache.http.HttpHost; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import java.io.IOException; public class ElasticsearchConsistencyExample { public static void main(String[] args) throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); UpdateRequest request = new UpdateRequest("your_index", "your_type", "your_id") .doc(XContentType.JSON, "field", "new_value") .retryOnConflict(3) .setRefreshPolicy(DocWriteRequest.RefreshPolicy.WAIT_UNTIL); try { UpdateResponse response = client.update(request, RequestOptions.DEFAULT); if (response.getResult() == DocWriteResponse.Result.CREATED || response.getResult() == DocWriteResponse.Result.UPDATED) { System.out.println("Document updated successfully"); } } catch (IOException e) { e.printStackTrace(); } finally { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } }
retryOnConflict(3)
: 设置更新冲突时的重试次数。setRefreshPolicy(DocWriteRequest.RefreshPolicy.WAIT_UNTIL)
: 确保在更新完成后,文档立即对搜索可见,进一步保证一致性。