背景

用户需求:近期数据查询速度快,较远历史数据运行查询速度慢?

  • 对于开发人员而言即数据的冷热分离,实现此功能有2个前提条件:
  1. 硬件:处理速度不同的硬件,最起码有读写速度不同的硬盘,如SSD、机械硬盘HDD。
  2. 软件配置:可以配置 不同的数据存储在不同的硬盘,如近期数据存储在SSD,较远历史数据存储在HDD。对于linux系统而言,存储于不同的硬盘就是存储在不同的路径。

elasticsearch的冷热分离配置主要依赖于分片分布规则设置。

es配置之分片分布规则设置

自定义分片分布规则

  • cluster.routing.allocation.awareness.attributes

    根据某个属性作为分片分布规则。
#设置节点属性rack_id及属性值rack_one
node.rack_id: rack_one
#设置rack_id属性作为分片分布规则
cluster.routing.allocation.awareness.attributes: rack_id
  • 可以为分片分布规则设置多个属性,例如:
cluster.routing.allocation.awareness.attributes: rack_id,zone

注意:当设置了分片分布属性时,如果集群中的节点没有设置其中任何一个属性,那么分片就不会分布到这个节点中。

强制分布规则

副本被分布到相同分布规则属性值的一群节点上,那么,我们可以强制分片规则为一个指定的值。

cluster.routing.allocation.awareness.force.zone.values: zone1,zone2
cluster.routing.allocation.awareness.attributes: zone

启动两个node.zone设置成zone1的节点,然后创建一个5个分片,一个副本的索引。索引建立完成后只有5个分片(没有副本),只有当我们启动node.zone设置成zone2的节点时,副本才会分配到那节点上。

上面配置的意思就是设置属性zone作为分布规则,并且属性zone的值为zone1/zone2,由于副本与主分片不分配在一类节点中,则副本分片到zone2节点中。

分片分布过滤

通过include/exclude过滤器来控制分片的分布。这些过滤器可以设置在索引级别上或集群级别上。

node.tag: hot
node.tag: cold
node.tag: value3 "index.routing.allocation.include.tag": "hot"
"index.routing.allocation.exclude.tag" : "value3"

include或exclude过滤器的值都会使用通配符来匹配,如value*。一个特别的属性名是_ip,它可以用来匹配节点的ip地址。

显然,一个节点可能拥有多个属性值,所有属性的名字和值都在配置文件中配置。如,下面是多个节点的配置:

node.group1: group1_value1
node.group2: group2_value4

同样的方法,include和exclude也可以设置多个值,如:

curl -XPUT localhost:9200/test/_settings -d '{
"index.routing.allocation.include.group1" : "xxx"
"index.routing.allocation.include.group2" : "yyy",
"index.routing.allocation.exclude.group3" : "zzz",
}'

上面的设置可以通过索引更新的api实时更新到索引上,允许实时移动索引分片。

集群范围的过滤器也可以定义,可以通过集群更新api实时更新到集群上。这些设置可以用来做让一些节点退出集群的操作。下面是通过ip地址去掉一个节点的操作:

curl -XPUT localhost:9200/_cluster/settings -d '{
"transient" : {
"cluster.routing.allocation.exclude._ip" : "10.0.0.1"
}
}'

冷热分离实践

  • step1:划分冷热节点
node.tag: hot
node.tag: cold
node.max_local_storage_nodes: 2 #允许每个机器启动两个es进程(可选)
  • step2:按时间规律等建索引。比如按天、按周建索引

索引模板logstash:所有 logstash* 的索引匹配的模板。

PUT /_template/logstash
{
"order": 0,
"template": "logstash*",
"settings": {
"index.routing.allocation.include.tag": "hot",
"index.refresh_interval": "30s",
"index.number_of_replicas": "1",
"index.number_of_shards": "1",
"index.translog.flush_threshold_ops": "30000"
}
}

“index.routing.allocation.include.tag”: “hot”,表示新建索引将分配到 node.tag = hot 的节点下

  • step3: 定时任务将历史索引分配到 cold 节点下。

    最新索引保存在hot节点,历史索引定时保存到cold节点。有2种方式:
  1. 自己写脚本,将历史索引标记为stale
PUT /index_name/_settings
{
"index.routing.allocation.include.tag" : "cold"
}

这样旧索引数据会自动迁移到cold集群上

  1. 安装 elasticsearch的命令行管理工具curator, 编写curator脚本,每天4点将历史索引分配到 cold 节点下
pip install elasticsearch-curator==5.x

# 将3天以前的 logstash* 索引分配到 cold 节点下
1:
action: allocation
description: "Apply shard allocation filtering rules to the specified indices"
options:
key: box_type
value: cold
allocation_type: require
wait_for_completion: true
timeout_override:
continue_if_exception: false
disable_action: false
filters:
- filtertype: pattern
kind: prefix
value: logstash-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 3

强制索引合并,每个分片1个分段。

2:
action: forcemerge
description: "Perform a forceMerge on selected indices to 'max_num_segments' per shard"
options:
max_num_segments: 1
delay:
timeout_override: 21600
continue_if_exception: false
disable_action: false
filters:
- filtertype: pattern
kind: prefix
value: logstash-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 3

读写分离探讨

  • 类似于mysql的读写分离,将副本数据存储于特点节点上。这个没办法通过自动配置完成,可以通过reroute api来手动进行索引分片的分配.

不过要想完全手动,必须先把cluster.routing.allocation.disable_allocation参数设置为true,禁止es进行自动索引分片分配,否则你从一节点把分片移到另外一个节点,那么另外一个节点的一个分片又会移到那个节点。

一共有三种操作,分别为:移动(move),取消(cancel)和分配(allocate)。下面分别介绍这三种情况:

  • 移动(move)

    把分片从一节点移动到另一个节点。可以指定索引名和分片号。
  • 取消(cancel)

    取消分配一个分片。可以指定索引名和分片号。node参数可以指定在那个节点取消正在分配的分片。allow_primary参数支持取消分配主分片。
  • 分配(allocate)

    分配一个未分配的分片到指定节点。可以指定索引名和分片号。node参数指定分配到那个节点。allow_primary参数可以强制分配主分片,不过这样可能导致数据丢失。
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
"commands" : [ {
"move" :
{
"index" : "test", "shard" : 0,
"from_node" : "node1", "to_node" : "node2"
}
},
"cancel" :
{
"index" : "test", "shard" : 0, "node" : "node1"
}
},
{
"allocate" : {
"index" : "test", "shard" : 1, "node" : "node3"
}
}
]
}'
  • 注意事项:
因为es的replica也是一个实际需要cpu和io的indexing过程,而且indexing本身也有要求要写够一定副本数来才算写入完成。所以,你即使只请求replica,也是有可能影响到写入的。

所以,你只能开启一个副本——因为写入副本数要求是从二个副本开始才有。

冷热数据查询

GET /_search?preference=xyzabc123
{
"query": {
"match": {
"title": "elasticsearch"
}
}
}

https://www.elastic.co/guide/en/elasticsearch/reference/master/search-request-preference.html?q=preference

参考文献

es高级用法之冷热分离的更多相关文章

  1. 让Elasticsearch集群冷热分离、读写分离【转】

    转自:https://blog.csdn.net/jiao_fuyou/article/details/50511255 根据Elasticsearch中文社区<ES冷热分离(读写分离) hot ...

  2. Elasticsearch使用小结之冷热分离

    Elasticsearch使用小结之冷热分离 索引迁移 索引setting中的index.routing.allocation.exclude和index.routing.allocation.inc ...

  3. Elasticsearch7.X ILM索引生命周期管理(冷热分离)

    Elasticsearch7.X ILM索引生命周期管理(冷热分离) 一.“索引生命周期管理”概述 Elasticsearch索引生命周期管理指:Elasticsearch从设置.创建.打开.关闭.删 ...

  4. ElasticSearch实战系列十: ElasticSearch冷热分离架构

    前言 本文主要介绍ElasticSearch冷热分离架构以及实现. 冷热分离架构介绍 冷热分离是目前ES非常火的一个架构,它充分的利用的集群机器的优劣来实现资源的调度分配.ES集群的索引写入及查询速度 ...

  5. redis的Linux系统安装与配置、redis的api使用、高级用法之慢查询、pipline事物

    今日内容概要 redis 的linux安装和配置 redis 的api使用 高级用法之慢查询 pipline事务 内容详细 1.redis 的linux安装和配置 # redis 版本选择问题 -最新 ...

  6. Visual Studio 宏的高级用法

    因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...

  7. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  8. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  9. Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)

    上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了.没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的 ...

随机推荐

  1. java -io 读取文件操作

    主要分为字节读取和字符读取,字节读取可以一个一个读取和字节数组读取,字符读取同样之,字符读取适合文本读取,字节读取皆可以 这里直接上代码,读取文件的9个小demo package com.io; im ...

  2. POJ3311 Hie with the Pie 【状压dp/TSP问题】

    题目链接:http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total ...

  3. Java基础语法知识你真的都会吗?

    第一阶段 JAVA基础知识 第二章 Java基础语法知识 在我们开始讲解程序之前,命名规范是我们不得不提的一个话题,虽说命名本应该是自由的,但是仍然有一定的"潜规则",通过你对命名 ...

  4. Spark Scala当中reduce的用法和例子

    [学习笔记] reduce将RDD中元素前两个传给输入函数,产生一个新的return值,将新产生的return值与RDD中下一个元素(即第三个元素)组成两个元素,再被传给输入函数,这样递归运作,直到最 ...

  5. Java web server 基本实现原理

    public class WebServer { //服务端Socket只要一个,所以定义成static, 同一时间只能一个线程访问(主线程) private static ServerSocket ...

  6. Dom4j 生成xml并格式化

    Document document = DocumentHelper.createDocument(); //创建root         Element root = document.addEle ...

  7. Python re 模块findall() 函数返回值展现方式详解

    findall 函数: 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表. 注意: match 和 search 是匹配一次 findall 匹配所有,mat ...

  8. NIT校赛-- 雷顿女士与分队

    题意:https://ac.nowcoder.com/acm/contest/2995/D 思路: 和最大子串很像,dp[i]=max(dp[i-1]+a[i],a[i]),要不和前面连一起,要不就是 ...

  9. 如何给Swagger加注释

    在Startup.cs文件中的ConfigureServices()方法中添加如下代码即可 services.AddSwaggerGen(options => { options.Swagger ...

  10. jQuery Validation ,调用valid方法时,不验证remote

    1.问题描述 model代码如下: remote对应的action如下: view代码如下: 单击按钮时,执行如下动作 当点击按钮时,我们发现,虽然后台action验证失败,但 还是执行返回true, ...