面试题答案
一键面试写入队列优化
- 增加队列容量:在应用层,适当增加写入队列的容量,防止因队列满而丢弃数据。例如,在Java中使用
LinkedBlockingQueue
时,增大其初始化容量。
BlockingQueue<Document> writeQueue = new LinkedBlockingQueue<>(1000);
- 限流机制:引入限流算法,如令牌桶算法,控制写入速度,避免因瞬间大量请求压垮ES集群。以Guava库为例:
RateLimiter limiter = RateLimiter.create(10); // 每秒允许10个请求
while (true) {
if (limiter.tryAcquire()) {
// 执行写入操作
}
}
- 异步写入:将同步写入改为异步写入,利用多线程或线程池来提高写入效率。例如在Python中使用
concurrent.futures
模块:
import concurrent.futures
import elasticsearch
es = elasticsearch.Elasticsearch()
def write_to_es(doc):
es.index(index='your_index', body=doc)
with concurrent.futures.ThreadPoolExecutor() as executor:
for doc in your_documents_list:
executor.submit(write_to_es, doc)
副本分配策略调整
- 动态副本调整:根据节点状态动态调整副本数量。当部分节点故障时,减少副本数量,提高写入性能。可以通过ES的API来实现:
PUT /your_index/_settings
{
"index": {
"number_of_replicas": 0
}
}
待集群恢复稳定后,再逐步增加副本数量:
PUT /your_index/_settings
{
"index": {
"number_of_replicas": 1
}
}
- 副本分配算法优化:修改ES配置文件(
elasticsearch.yml
),调整副本分配策略。例如,设置cluster.routing.allocation.awareness.attributes
属性,使副本分配在不同机架或数据中心,提高集群的容错性:
cluster.routing.allocation.awareness.attributes: rack_id
故障节点数据恢复
- 节点重启:首先尝试重启故障节点。检查节点日志(位于
logs
目录下),查看是否有可修复的错误,如内存溢出等。根据日志提示调整节点配置,如增加堆内存:
export ES_HEAP_SIZE=4g
./bin/elasticsearch
- 数据重建:如果重启无效,从其他节点重新复制数据。可以利用ES的自动恢复机制,确保集群状态为
yellow
(表示部分副本缺失)或green
(表示所有副本都正常)。如果数据丢失严重,可以从备份中恢复数据,例如使用Snapshot和Restore功能:
# 创建快照
PUT /_snapshot/my_backup_repository/my_snapshot
{
"indices": "your_index",
"ignore_unavailable": true,
"include_global_state": false
}
# 从快照恢复
POST /_snapshot/my_backup_repository/my_snapshot/_restore
{
"indices": "your_index",
"ignore_unavailable": true,
"include_global_state": false
}
- 节点替换:若故障节点硬件损坏,替换新的节点。在新节点上安装ES,并配置与原节点相同的集群名称和网络设置。启动新节点后,ES会自动将数据复制到新节点,恢复集群状态。