【网易/杭州】寻找 es 开发工程师,不用 996
网易杭州研究院正在寻找 es 开发工程师,待遇从优,福利给力!
职位描述
1、负责公司搜索平台的研发,包括搜索核心技术的跟进和实施,为网易集团内部互联网产品业务提供基础搜索支撑服务;
2、打造高性能、高可靠的统一分布式搜索平台,提供文本/向量检索、灵活的排序算法框架、简便的运维管理平台等功能;
3、和产品和业务紧密联系,不断迭代和优化搜索系统产品体验。
职位要求
1、本科及以上学历,有1年以上搜索引擎或信息检索相关工作经验;
2、深入了解全文检索技术及原理,熟悉分布式搜索引擎架构和实现;
3、Java基础扎实,了解JVM原理,有分布式系统开发经验;
4、熟悉开源Lucene/Elasticsearch原理或有相关开发经验者优先考虑;
5、良好的理解与表达能力,优秀的团队合作和自我驱动能力。
工作地点:杭州
简历投递:hzchenliangliang <AT> corp.netease.com
网易杭州研究院正在寻找 es 开发工程师,待遇从优,福利给力!
职位描述
1、负责公司搜索平台的研发,包括搜索核心技术的跟进和实施,为网易集团内部互联网产品业务提供基础搜索支撑服务;
2、打造高性能、高可靠的统一分布式搜索平台,提供文本/向量检索、灵活的排序算法框架、简便的运维管理平台等功能;
3、和产品和业务紧密联系,不断迭代和优化搜索系统产品体验。
职位要求
1、本科及以上学历,有1年以上搜索引擎或信息检索相关工作经验;
2、深入了解全文检索技术及原理,熟悉分布式搜索引擎架构和实现;
3、Java基础扎实,了解JVM原理,有分布式系统开发经验;
4、熟悉开源Lucene/Elasticsearch原理或有相关开发经验者优先考虑;
5、良好的理解与表达能力,优秀的团队合作和自我驱动能力。
工作地点:杭州
简历投递:hzchenliangliang <AT> corp.netease.com 收起阅读 »
Elasticsearch索引拆分方案
Elasticsearch索引拆分方案
[TOC]
一、概况
项目中,由于Elasticsearch单个索引数据量大,索引中部分数据不常用,在搜索和写入文档时,效率较低。为了减小单个索引的数据量,提升搜索和文档写入效率,将大索引根据一定的规则拆分为小的索引。拆分索引的关键点在于建立索引,文档同步,多索引搜索。
建立索引的关键问题是索引的设置以及字段的属性设置,最常见的问题是,某个字段我们希望Elasticsearch 按照我们的想法进行分词。采用自动生成索引(默认模板),索引字段的类型就会根据第一条文档的数据进行字段转换,无法实现具体某个字段使用我们想要的分词方式。另外就是无法使用自定义分词器,索引的默认分片数为5,无法根据我们制定的分片数进行分配。
为了实现我们这种自动创建索引的特殊要求,Elasticsearch也提供了索引模板API。
索引模板,就是创建索引的模板,模板中包含公共的配置(Settings)和映射(Mappings),并包含一个简单触发条件,及条件满足时使用该模板创建一个新的索引。
模板只在创建索引时应用。更改模板不会对现有索引产生影响。当使用create index API时,作为create index调用的一部分定义的设置/映射将优先于模板中定义的任何匹配设置/映射。
文档同步和搜索,我们都采用了别名的形式。索引别名,就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任何一个需要索引名的API来使用,别名不能与索引具有相同的名称。别名带给我们极大的灵活性,允许我们在运行的集群中可以无缝的从一个索引切换到另一个索引,给多个索引分组 ,给索引的一个子集创建。因为使用别名,你的应用可以在零停机的情况下从旧索引迁移到新索引。
由于文档同步,必须指定一个唯一的索引才能成功。原来单索引时,我们的索引采取了 “索引名称_v1”的形式,为方便在零停机的情况下重建索引,文档更新也新建了一个专门的索引别名。 拆分索引后,索引名称规范为“索引名称_YYMM”按月拆分(包括但不限于此种方式),就会出现多个索引,此时就不在方便新增专门的索引别名用于文档更新,反而用索引名字直接进行文档更新,就会更加的方便,直接和准确。
文档同步使用索引名称,搜索依旧使用别名的形式。多个索引,有相同的别名,索引拆分,文档分属不同的索引,但因为有相同的别名,使用别名搜索时,依然可以将数据搜索出来。
通过建立索引,文档同步,多索引搜索实现了单索引到多索引的拆分。数据还是那些数据,依然能搜索出来,索引数变多了,每个索引的数据减少,同步文档速度就可以提高。搜索也可以根据业务需求只查询部分索引,提升了查询速度,也可以查询所有数据,根据实际场景可自由变换。
二、索引拆分规则
索引拆分,可以根据创建时间拆分,如:”索引名称_yyyyMM“,”索引名称_yyyy“;也可以根据主键ID求余的方式来进行拆分,如:”索引名称_0“,”索引名称_1“。
具体的拆分规则根据业务需要进行,需要注意的是,无论根据创建时间还是根据主键ID求余来拆分,都要求根据拆分的值,是文档中不变的值,才能唯一确定一个索引,进行文档的存储,如:主键ID,创建时间;不可为变化的值,有可能变化的值,就无法唯一确定一个索引进行文档存储,如:状态,那就会出现当前在这个索引,状态改变后再另外的索引,这样每个索引都有同一条状态不同的数据,搜索时就会不准确。
本文将根据创建时间进行索引拆分。
思路:
- 创建索引模板
- 同步文档时,选用的索引名称以"索引名称_yyyyMM"命名,自动创建带别名的索引
- 如果文档同步到新索引,原索引中的文档需删除
三、创建索引模板
以商品评论索引为例,将单索引拆分为多索引,根据以下规则,在同步文档时,如果无索引会字段根据模板生成:
- 索引名称的规则“goods_comment_202010”
- 索引别名为“goods_comment”
- number_of_shards分片数为3
- 配置Settings
- 定义Mappings字段及其类型
具体模板如下所示:
{
"order" : 0,
"index_patterns" : [
"goods_comment*"
],
"settings" : {
"index" : {
"max_result_window" : "100000",
"analysis" : {
"filter" : {
"by_stop_filter" : {
"type" : "stop",
"stopwords" : [
" "
]
},
"pinyin_first_letter_and_full_pinyin_filter" : {
"keep_none_chinese_in_first_letter" : "true",
"lowercase" : "true",
"keep_original" : "true",
"keep_first_letter" : "true",
"trim_whitespace" : "true",
"type" : "pinyin",
"keep_none_chinese" : "true",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
},
"by_synonym_filter" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonym.txt"
},
"full_pinyin_filter" : {
"keep_none_chinese_in_first_letter" : "true",
"lowercase" : "true",
"keep_original" : "true",
"keep_first_letter" : "false",
"trim_whitespace" : "true",
"type" : "pinyin",
"keep_none_chinese" : "true",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
}
},
"char_filter" : {
"by_char_filter" : {
"type" : "mapping",
"mappings" : [
"| => |"
]
}
},
"analyzer" : {
"by_max_word" : {
"filter" : [
"by_synonym_filter",
"lowercase"
],
"char_filter" : [
"html_strip"
],
"type" : "custom",
"tokenizer" : "ik_max_word"
}
},
"tokenizer" : {
"my_pinyin" : {
"lowercase" : "true",
"keep_original" : "true",
"remove_duplicated_term" : "true",
"keep_separate_first_letter" : "false",
"type" : "pinyin",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
}
}
},
"number_of_shards" : "3",
"number_of_replicas" : "1"
}
},
"mappings" : {
"_doc" : {
"properties" : {
"is_img" : {
"type" : "integer"
},
"gid" : {
"type" : "integer"
},
"pubtime" : {
"type" : "integer"
}
....
}
}
},
"aliases" : {
"goods_comment" : { }
}
}
上述模板定义,看似复杂,拆分来看,主要为如下几个部分:
{
"order": 0, // 模板优先级
"index_patterns": ["goods_comment*"],// 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {...} // 索引的别名
}
3.1 模板优先级
有时候,一个模板可能绝大部分符合新建索引的需求,但是局部需要微调,此时,如果复制旧的模板,修改该模板后,成为一个新的索引模板即可达到我们的需求,但是这操作略显重复。此时,可以采用模板叠加与覆盖来操作。模板的优先级是通过模板中的 order 字段定义的,数字越大,优先级越高。 如下为定义所有以 te 开头的索引的模板:
{
"order": 0,
"index_patterns": "te*",
"settings": {
"number_of_shards": 1
},
"mappings": {
"type1": {
"_source": {
"enabled": false
}
}
}
}
索引模板是有序合并的。如何想单独修改某一小类索引的一两处单独设置,可以在累加一层模板。
{
"order": 1,
"index_patterns": "tete*",
"settings": {
"number_of_shards": 2
},
"mappings": {
"type1": {
"_all": {
"enabled": false
}
}
}
}
上述第一个模板的 order 为0,第二个模板的 order 为1,优先级高于第一个模板,其会覆盖第一个模板中的相同项。所以对于所有以 tete 开头的索引模板效果如下:
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"type1": {
"_source": {
"enabled": false
},
"_all": {
"enabled": false
}
}
}
}
两个模板叠加了,项目的字段,优先级高的覆盖了优先级低的,如分片数。
3.2 模板匹配的名称
索引模板中的 "index_patterns" 字段定义的是该索引模板所应用的索引情况。如 "index_patterns": "tete*" 所表示的含义是,当新建索引时,所有以 tete 开头的索引都会自动匹配到该索引模板。利用该模板进行相应的设置和字段添加等。
3.3 settings 部分
索引模板中的 settings 部分一般定义的是索引的主分片、拷贝分片、刷新时间、自定义分析器等。常见的 settings 部分结构如下:
"settings": {
"index": {
"analysis": {...}, // 自定义的分析器
"number_of_shards": "32", // 主分片的个数
"number_of_replicas": "1", // 主分片的拷贝分片个数
"refresh_interval": "5s" // 刷新时间
}
}
建立的索引,不会立马查到,这是为什么 Elasticsearch 为 near-real-time(接近实时)的原因,需要配置刷新时间,默认的是 1s。settings 的设置中,重点是自定义分析器的设置。
-
分析器是三个顺序执行的组件的结合。他们分别是字符过滤器、分词器、标记过滤器。字符过滤器是让字符串在被分词前变得更加整洁。一个分析器可能包含零到多个字符过滤器(character_filter)。
-
分词器将字符串分割成单独的词(terms)或标记(tokens)。一个分析器必须包含一个分词器。
- 分词器分词的结果的标记流会根据各自的情况,传递给特定的标记过滤器。标记过滤器可能修改、添加或删除标记。
创建的创建自定义分析器结构如下:
"settings": {
"index": {
"analysis": {
"char_filter": { ... }, // 用户自定义字符过滤器
"tokenizer": { ... }, // 用户自定义分词器
"filter": { ... }, // 用户自定义标记过滤器
"analyzer": { ... } // 用户自定义分析器
},
...
}
}
3.4 索引类型的字段映射
索引模板中,映射字段所对应的常用结构是:
"mappings": {
"_doc": { // 索引下的类型 _doc 应用该映射
"dynamic_templates": [ ... ], // 动态映射部分,用于未定义的 my_type 下字段
"properties": { ... } // 自定义字段的响应映射
}
}
"_doc" 是索引下的一个类型,Elasticsearch 7.x仅支持"_doc"作为索引类型,Elasticsearch 6.x推荐使用"_doc"为索引类型。
动态映射
动态映射 "dynamic_templates" 字段对应的是一个数组,数组中的元素是一个个字段的映射模板。每个字段的映射模板都有一个名字用户描述这个模板的用途,一个 mapping 字段由于指明这个映射如何使用,和至少一个参数(例如 match)来定义这个模板适用于哪个字段。 dynamic_templates 字段对应的字段模板结构如下:
{
"string_fields": { // 字段映射模板的名称,一般为"类型_fields"的命名方式
"match": "*", // 匹配的字段名为所有
"match_mapping_type": "string", // 限制匹配的字段类型,只能是 string 类型
"mapping": { ... } // 字段的处理方式
}
自定义字段映射
针对索引类型中存在的字段,除了可以采用动态模板的方式,还可以采用定义定义的方式,常见的自定义结构如下:
"mappings": {
"my_type": {
"dynamic_templates": [ ... ],
"properties": {
"user_city": { // 字段名
"analyzer": "lowercase_analyzer", // 字段分析器
"index": "analyzed", // 字段索引方式定义索引
"type": "string", // 字段数据类型定义为 string
"fields": { // 定义一个名为 user_city.raw 的嵌入的不分析字段
"raw": {
"ignore_above": 512,
"index": "not_analyzed",
"type": "string"
}
}
},
"money":{
"type": "double",
"doc_values": true
}
...
}
}
}
3.5 别名
即使你认为现在的索引设计已经是完美的了,当你的应用在生产环境使用时,还是有可能在今后有一些改变的。所以请做好准备:在应用中使用别名而不是索引。然后你就可以在任何时候重建索引。别名的开销很小,应当广泛使用。利用索引别名,可以实现零停机时间重新索引。 定义方式如下:
{
"order": 0, // 模板优先级
"index_patterns": "goods_comment*", // 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {
"goods_comment":{}
}
}
以上只是简单的介绍了索引模板和模板内的组成部分的介绍,详情请见Elasticsearch官方文档。
有了以上的知识,我们就可以利用索引模板的API,来对模板进行创建,查询,删除操作了。
3.6 索引模板管理
创建索引模板
PUT _template/goods_comment_template
{
"order": 0, // 模板优先级
"index_patterns": "goods_comment*", // 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {
"goods_comment":{}
}
}
查看索引模板
GET _template // 查看所有模板
GET _template/temp* // 查看与通配符相匹配的模板
GET _template/temp1,temp2 // 查看多个模板
GET _template/shop_template // 查看指定模板
判断模板是否存在
HEAD _template/shop_tem
结果: a) 如果存在, 响应结果是: 200 - OK b) 如果不存在, 响应结果是: 404 - Not Found
删除索引模板
DELETE _template/shop_template // 删除上述创建的模板
如果模板不存在, 将抛出404 错误
四、同步文档,自动创建索引
前面创建了商品评论的索引模板(goods_comment_template),同步文档时,指定索引名称为“goods_comment_202010”,如果索引不存在,便会创建名为“goods_comment_202010”的索引,同时创建好“goods_comment”别名。索引的settings和mappings都会根据模板定义的规则生成好。索引创建成功,此时该索引便能正常使用啦。
商品评论业务中,同步文档是在代码中实现,需要根据商品评论的创建时间,以“goods_comment_yyyyMM”的形式获取完整的索引名称(如:goods_comment_202010),同步文档指定goods_comment_202010,即可将数据同步到该索引。
五、别名搜索
多个商品评论索引,每个索引都有“goods_comment“别名,使用别名进行搜索,便能从这多个索引中获取数据。
同理,其他业务索引实现搜索,都要求使用别名形式。
六、可能存在的问题点
索引创建后,并不是一成不变的,随着业务的发展,新增字段也是较常见的。原来单索引,新增一个字段,只需要在mappings新增字段,重建索引,迁移数据,切换别名即可。拆分后的多索引,工作量便会成被增加。
修改索引模板,只会对后续生成的索引有作用,之前生成的索引,如需调整,需要手动或者使用脚本的形式进行重建并迁移数据。
七、附录
demo演示,也是体验索引拆分的一个实现过程。
7.1 查询索引模板列表
查看ES中的所有索引模板列表
命令:
GET _cat/templates?v
结果:
name index_patterns order version
kibana_index_template:.kibana [.kibana] 0
.monitoring-kibana [.monitoring-kibana-6-*] 0 6050399
.management-beats [.management-beats] 0 67000
7.2 创建索引模板
命令:
PUT _template/demo_template
{
"order": 0,
"index_patterns": [
"demo*"
],
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 0,
"max_result_window": 100000
}
},
"aliases": {
"demo": {}
}
}
结果:
{
"acknowledged" : true
}
7.3 查看索引模板详情
命令:
GET _template/demo_template
结果:
{
"demo_template" : {
"order" : 0,
"index_patterns" : [
"demo*"
],
"settings" : {
"index" : {
"max_result_window" : "100000",
"number_of_shards" : "2",
"number_of_replicas" : "0"
}
},
"mappings" : { },
"aliases" : {
"demo" : { }
}
}
}
7.4 查询索引数据
命令:
GET demo_v1/_search
结果:
{
"error" : {
"root_cause" : [
{
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo_v1",
"index_uuid" : "_na_",
"index" : "demo_v1"
}
],
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo_v1",
"index_uuid" : "_na_",
"index" : "demo_v1"
},
"status" : 404
}
7.5 创建文档
在此之前demo_v1索引不存在,通过创建文档,自动生成索引,新创建的demo_v1将根据demo_template索引模板生成。
命令:
POST demo_v1/_doc
{
"id": 1,
"title": "这是一条数据"
}
结果:
{
"_index" : "demo_v1",
"_type" : "_doc",
"_id" : "20upIHUBO6Fj2CIJUFPr",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查看数据
GET demo_v1/_search 用索引名称进行查询
GET demo/_search 用别名进行查询
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 2,
"successful" : 2,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "demo_v1",
"_type" : "_doc",
"_id" : "20upIHUBO6Fj2CIJUFPr",
"_score" : 1.0,
"_source" : {
"id" : 1,
"title" : "这是一条数据"
}
}
]
}
}
发现使用索引名称和别名都能搜索出来。但是我们并未单独创建索引别名。我们来查看一下demo_v1索引的结构。
GET demo_v1
{
"demo_v1" : {
"aliases" : {
"demo" : { }
},
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "long"
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "2",
"provided_name" : "demo_v1",
"max_result_window" : "100000",
"creation_date" : "1602570768526",
"number_of_replicas" : "0",
"uuid" : "WrXtDB5eRzmU-xX1vAUCrA",
"version" : {
"created" : "6070099"
}
}
}
}
}
我们可以看到,demo_v1 索引中的数据:
- 分片数(number_of_shards): 2
- 副本(number_of_replicas): 0
- 别名(aliases):demo
- 最大结果窗口(max_result_window):100000
这些都是我们在demo_template模板中设置的,在自动创建索引时,根据索引模板的index_patterns值,只要我们的索引名称是以“demo”为前缀,都会根据该模板生成索引。因此,无论是demo_v1,还是demo_v2,只要是以“demo”为前缀,直接创建文档,如果不存在索引,ES也会自动给我们创建以“demo_template”为模板的索引。实现索引拆分最关键的点,就在于索引模板。
同样,我们通过创建文档,来生成一个没有索引模板的索引进行对比。
查询demo
GET demo/_search
确定demo索引不存在
{
"error" : {
"root_cause" : [
{
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo",
"index_uuid" : "_na_",
"index" : "demo"
}
],
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo",
"index_uuid" : "_na_",
"index" : "demo"
},
"status" : 404
}
创建一条文档
POST demo/_doc
{
"id": 1,
"title": "这是一条数据"
}
创建成功
{
"_index" : "demo",
"_type" : "_doc",
"_id" : "PmXEIHUBwM4PCvJbG7Xw",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查看数据
GET demo/_search
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 2,
"successful" : 2,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "demo",
"_type" : "_doc",
"_id" : "PmXEIHUBwM4PCvJbG7Xw",
"_score" : 1.0,
"_source" : {
"id" : 1,
"title" : "这是一条数据"
}
}
]
}
}
数据同步成功,索引也因此创建完成,我们来看看这个索引结构
GET demo
{
"demo" : {
"aliases" : { },
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "long"
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "2",
"provided_name" : "demo",
"creation_date" : "1602572524390",
"number_of_replicas" : "1",
"uuid" : "p8kNddGzQzWOaz5xLcSWhA",
"version" : {
"created" : "6070099"
}
}
}
}
}
我们可以看到,demo索引中的数据:
- 分片数(number_of_shards): 2
- 副本(number_of_replicas): 1
- 别名(aliases):无
- 最大结果窗口(max_result_window):无
为了直观比较,请看下表:
有索引模板(demo_v1) | 无索引模板(demo) | |
---|---|---|
number_of_shards | 2 | 2 |
number_of_replicas | 0 | 1 |
aliases | demo | 无 |
max_result_window | 10w | 无,默认是1w |
上表可知,通过索引模板的创建的索引,有利于我们更好的掌控索引的结构。
通过demo演示,我们可以进一步的理解索引拆分的一个过程及其实现原理,重点在索引模板。
八、参考
Elasticsearch索引拆分方案
[TOC]
一、概况
项目中,由于Elasticsearch单个索引数据量大,索引中部分数据不常用,在搜索和写入文档时,效率较低。为了减小单个索引的数据量,提升搜索和文档写入效率,将大索引根据一定的规则拆分为小的索引。拆分索引的关键点在于建立索引,文档同步,多索引搜索。
建立索引的关键问题是索引的设置以及字段的属性设置,最常见的问题是,某个字段我们希望Elasticsearch 按照我们的想法进行分词。采用自动生成索引(默认模板),索引字段的类型就会根据第一条文档的数据进行字段转换,无法实现具体某个字段使用我们想要的分词方式。另外就是无法使用自定义分词器,索引的默认分片数为5,无法根据我们制定的分片数进行分配。
为了实现我们这种自动创建索引的特殊要求,Elasticsearch也提供了索引模板API。
索引模板,就是创建索引的模板,模板中包含公共的配置(Settings)和映射(Mappings),并包含一个简单触发条件,及条件满足时使用该模板创建一个新的索引。
模板只在创建索引时应用。更改模板不会对现有索引产生影响。当使用create index API时,作为create index调用的一部分定义的设置/映射将优先于模板中定义的任何匹配设置/映射。
文档同步和搜索,我们都采用了别名的形式。索引别名,就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任何一个需要索引名的API来使用,别名不能与索引具有相同的名称。别名带给我们极大的灵活性,允许我们在运行的集群中可以无缝的从一个索引切换到另一个索引,给多个索引分组 ,给索引的一个子集创建。因为使用别名,你的应用可以在零停机的情况下从旧索引迁移到新索引。
由于文档同步,必须指定一个唯一的索引才能成功。原来单索引时,我们的索引采取了 “索引名称_v1”的形式,为方便在零停机的情况下重建索引,文档更新也新建了一个专门的索引别名。 拆分索引后,索引名称规范为“索引名称_YYMM”按月拆分(包括但不限于此种方式),就会出现多个索引,此时就不在方便新增专门的索引别名用于文档更新,反而用索引名字直接进行文档更新,就会更加的方便,直接和准确。
文档同步使用索引名称,搜索依旧使用别名的形式。多个索引,有相同的别名,索引拆分,文档分属不同的索引,但因为有相同的别名,使用别名搜索时,依然可以将数据搜索出来。
通过建立索引,文档同步,多索引搜索实现了单索引到多索引的拆分。数据还是那些数据,依然能搜索出来,索引数变多了,每个索引的数据减少,同步文档速度就可以提高。搜索也可以根据业务需求只查询部分索引,提升了查询速度,也可以查询所有数据,根据实际场景可自由变换。
二、索引拆分规则
索引拆分,可以根据创建时间拆分,如:”索引名称_yyyyMM“,”索引名称_yyyy“;也可以根据主键ID求余的方式来进行拆分,如:”索引名称_0“,”索引名称_1“。
具体的拆分规则根据业务需要进行,需要注意的是,无论根据创建时间还是根据主键ID求余来拆分,都要求根据拆分的值,是文档中不变的值,才能唯一确定一个索引,进行文档的存储,如:主键ID,创建时间;不可为变化的值,有可能变化的值,就无法唯一确定一个索引进行文档存储,如:状态,那就会出现当前在这个索引,状态改变后再另外的索引,这样每个索引都有同一条状态不同的数据,搜索时就会不准确。
本文将根据创建时间进行索引拆分。
思路:
- 创建索引模板
- 同步文档时,选用的索引名称以"索引名称_yyyyMM"命名,自动创建带别名的索引
- 如果文档同步到新索引,原索引中的文档需删除
三、创建索引模板
以商品评论索引为例,将单索引拆分为多索引,根据以下规则,在同步文档时,如果无索引会字段根据模板生成:
- 索引名称的规则“goods_comment_202010”
- 索引别名为“goods_comment”
- number_of_shards分片数为3
- 配置Settings
- 定义Mappings字段及其类型
具体模板如下所示:
{
"order" : 0,
"index_patterns" : [
"goods_comment*"
],
"settings" : {
"index" : {
"max_result_window" : "100000",
"analysis" : {
"filter" : {
"by_stop_filter" : {
"type" : "stop",
"stopwords" : [
" "
]
},
"pinyin_first_letter_and_full_pinyin_filter" : {
"keep_none_chinese_in_first_letter" : "true",
"lowercase" : "true",
"keep_original" : "true",
"keep_first_letter" : "true",
"trim_whitespace" : "true",
"type" : "pinyin",
"keep_none_chinese" : "true",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
},
"by_synonym_filter" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonym.txt"
},
"full_pinyin_filter" : {
"keep_none_chinese_in_first_letter" : "true",
"lowercase" : "true",
"keep_original" : "true",
"keep_first_letter" : "false",
"trim_whitespace" : "true",
"type" : "pinyin",
"keep_none_chinese" : "true",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
}
},
"char_filter" : {
"by_char_filter" : {
"type" : "mapping",
"mappings" : [
"| => |"
]
}
},
"analyzer" : {
"by_max_word" : {
"filter" : [
"by_synonym_filter",
"lowercase"
],
"char_filter" : [
"html_strip"
],
"type" : "custom",
"tokenizer" : "ik_max_word"
}
},
"tokenizer" : {
"my_pinyin" : {
"lowercase" : "true",
"keep_original" : "true",
"remove_duplicated_term" : "true",
"keep_separate_first_letter" : "false",
"type" : "pinyin",
"limit_first_letter_length" : "16",
"keep_full_pinyin" : "true"
}
}
},
"number_of_shards" : "3",
"number_of_replicas" : "1"
}
},
"mappings" : {
"_doc" : {
"properties" : {
"is_img" : {
"type" : "integer"
},
"gid" : {
"type" : "integer"
},
"pubtime" : {
"type" : "integer"
}
....
}
}
},
"aliases" : {
"goods_comment" : { }
}
}
上述模板定义,看似复杂,拆分来看,主要为如下几个部分:
{
"order": 0, // 模板优先级
"index_patterns": ["goods_comment*"],// 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {...} // 索引的别名
}
3.1 模板优先级
有时候,一个模板可能绝大部分符合新建索引的需求,但是局部需要微调,此时,如果复制旧的模板,修改该模板后,成为一个新的索引模板即可达到我们的需求,但是这操作略显重复。此时,可以采用模板叠加与覆盖来操作。模板的优先级是通过模板中的 order 字段定义的,数字越大,优先级越高。 如下为定义所有以 te 开头的索引的模板:
{
"order": 0,
"index_patterns": "te*",
"settings": {
"number_of_shards": 1
},
"mappings": {
"type1": {
"_source": {
"enabled": false
}
}
}
}
索引模板是有序合并的。如何想单独修改某一小类索引的一两处单独设置,可以在累加一层模板。
{
"order": 1,
"index_patterns": "tete*",
"settings": {
"number_of_shards": 2
},
"mappings": {
"type1": {
"_all": {
"enabled": false
}
}
}
}
上述第一个模板的 order 为0,第二个模板的 order 为1,优先级高于第一个模板,其会覆盖第一个模板中的相同项。所以对于所有以 tete 开头的索引模板效果如下:
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"type1": {
"_source": {
"enabled": false
},
"_all": {
"enabled": false
}
}
}
}
两个模板叠加了,项目的字段,优先级高的覆盖了优先级低的,如分片数。
3.2 模板匹配的名称
索引模板中的 "index_patterns" 字段定义的是该索引模板所应用的索引情况。如 "index_patterns": "tete*" 所表示的含义是,当新建索引时,所有以 tete 开头的索引都会自动匹配到该索引模板。利用该模板进行相应的设置和字段添加等。
3.3 settings 部分
索引模板中的 settings 部分一般定义的是索引的主分片、拷贝分片、刷新时间、自定义分析器等。常见的 settings 部分结构如下:
"settings": {
"index": {
"analysis": {...}, // 自定义的分析器
"number_of_shards": "32", // 主分片的个数
"number_of_replicas": "1", // 主分片的拷贝分片个数
"refresh_interval": "5s" // 刷新时间
}
}
建立的索引,不会立马查到,这是为什么 Elasticsearch 为 near-real-time(接近实时)的原因,需要配置刷新时间,默认的是 1s。settings 的设置中,重点是自定义分析器的设置。
-
分析器是三个顺序执行的组件的结合。他们分别是字符过滤器、分词器、标记过滤器。字符过滤器是让字符串在被分词前变得更加整洁。一个分析器可能包含零到多个字符过滤器(character_filter)。
-
分词器将字符串分割成单独的词(terms)或标记(tokens)。一个分析器必须包含一个分词器。
- 分词器分词的结果的标记流会根据各自的情况,传递给特定的标记过滤器。标记过滤器可能修改、添加或删除标记。
创建的创建自定义分析器结构如下:
"settings": {
"index": {
"analysis": {
"char_filter": { ... }, // 用户自定义字符过滤器
"tokenizer": { ... }, // 用户自定义分词器
"filter": { ... }, // 用户自定义标记过滤器
"analyzer": { ... } // 用户自定义分析器
},
...
}
}
3.4 索引类型的字段映射
索引模板中,映射字段所对应的常用结构是:
"mappings": {
"_doc": { // 索引下的类型 _doc 应用该映射
"dynamic_templates": [ ... ], // 动态映射部分,用于未定义的 my_type 下字段
"properties": { ... } // 自定义字段的响应映射
}
}
"_doc" 是索引下的一个类型,Elasticsearch 7.x仅支持"_doc"作为索引类型,Elasticsearch 6.x推荐使用"_doc"为索引类型。
动态映射
动态映射 "dynamic_templates" 字段对应的是一个数组,数组中的元素是一个个字段的映射模板。每个字段的映射模板都有一个名字用户描述这个模板的用途,一个 mapping 字段由于指明这个映射如何使用,和至少一个参数(例如 match)来定义这个模板适用于哪个字段。 dynamic_templates 字段对应的字段模板结构如下:
{
"string_fields": { // 字段映射模板的名称,一般为"类型_fields"的命名方式
"match": "*", // 匹配的字段名为所有
"match_mapping_type": "string", // 限制匹配的字段类型,只能是 string 类型
"mapping": { ... } // 字段的处理方式
}
自定义字段映射
针对索引类型中存在的字段,除了可以采用动态模板的方式,还可以采用定义定义的方式,常见的自定义结构如下:
"mappings": {
"my_type": {
"dynamic_templates": [ ... ],
"properties": {
"user_city": { // 字段名
"analyzer": "lowercase_analyzer", // 字段分析器
"index": "analyzed", // 字段索引方式定义索引
"type": "string", // 字段数据类型定义为 string
"fields": { // 定义一个名为 user_city.raw 的嵌入的不分析字段
"raw": {
"ignore_above": 512,
"index": "not_analyzed",
"type": "string"
}
}
},
"money":{
"type": "double",
"doc_values": true
}
...
}
}
}
3.5 别名
即使你认为现在的索引设计已经是完美的了,当你的应用在生产环境使用时,还是有可能在今后有一些改变的。所以请做好准备:在应用中使用别名而不是索引。然后你就可以在任何时候重建索引。别名的开销很小,应当广泛使用。利用索引别名,可以实现零停机时间重新索引。 定义方式如下:
{
"order": 0, // 模板优先级
"index_patterns": "goods_comment*", // 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {
"goods_comment":{}
}
}
以上只是简单的介绍了索引模板和模板内的组成部分的介绍,详情请见Elasticsearch官方文档。
有了以上的知识,我们就可以利用索引模板的API,来对模板进行创建,查询,删除操作了。
3.6 索引模板管理
创建索引模板
PUT _template/goods_comment_template
{
"order": 0, // 模板优先级
"index_patterns": "goods_comment*", // 模板匹配的名称方式
"settings": {...}, // 索引设置
"mappings": {...}, // 索引中各字段的映射定义
"aliases": {
"goods_comment":{}
}
}
查看索引模板
GET _template // 查看所有模板
GET _template/temp* // 查看与通配符相匹配的模板
GET _template/temp1,temp2 // 查看多个模板
GET _template/shop_template // 查看指定模板
判断模板是否存在
HEAD _template/shop_tem
结果: a) 如果存在, 响应结果是: 200 - OK b) 如果不存在, 响应结果是: 404 - Not Found
删除索引模板
DELETE _template/shop_template // 删除上述创建的模板
如果模板不存在, 将抛出404 错误
四、同步文档,自动创建索引
前面创建了商品评论的索引模板(goods_comment_template),同步文档时,指定索引名称为“goods_comment_202010”,如果索引不存在,便会创建名为“goods_comment_202010”的索引,同时创建好“goods_comment”别名。索引的settings和mappings都会根据模板定义的规则生成好。索引创建成功,此时该索引便能正常使用啦。
商品评论业务中,同步文档是在代码中实现,需要根据商品评论的创建时间,以“goods_comment_yyyyMM”的形式获取完整的索引名称(如:goods_comment_202010),同步文档指定goods_comment_202010,即可将数据同步到该索引。
五、别名搜索
多个商品评论索引,每个索引都有“goods_comment“别名,使用别名进行搜索,便能从这多个索引中获取数据。
同理,其他业务索引实现搜索,都要求使用别名形式。
六、可能存在的问题点
索引创建后,并不是一成不变的,随着业务的发展,新增字段也是较常见的。原来单索引,新增一个字段,只需要在mappings新增字段,重建索引,迁移数据,切换别名即可。拆分后的多索引,工作量便会成被增加。
修改索引模板,只会对后续生成的索引有作用,之前生成的索引,如需调整,需要手动或者使用脚本的形式进行重建并迁移数据。
七、附录
demo演示,也是体验索引拆分的一个实现过程。
7.1 查询索引模板列表
查看ES中的所有索引模板列表
命令:
GET _cat/templates?v
结果:
name index_patterns order version
kibana_index_template:.kibana [.kibana] 0
.monitoring-kibana [.monitoring-kibana-6-*] 0 6050399
.management-beats [.management-beats] 0 67000
7.2 创建索引模板
命令:
PUT _template/demo_template
{
"order": 0,
"index_patterns": [
"demo*"
],
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 0,
"max_result_window": 100000
}
},
"aliases": {
"demo": {}
}
}
结果:
{
"acknowledged" : true
}
7.3 查看索引模板详情
命令:
GET _template/demo_template
结果:
{
"demo_template" : {
"order" : 0,
"index_patterns" : [
"demo*"
],
"settings" : {
"index" : {
"max_result_window" : "100000",
"number_of_shards" : "2",
"number_of_replicas" : "0"
}
},
"mappings" : { },
"aliases" : {
"demo" : { }
}
}
}
7.4 查询索引数据
命令:
GET demo_v1/_search
结果:
{
"error" : {
"root_cause" : [
{
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo_v1",
"index_uuid" : "_na_",
"index" : "demo_v1"
}
],
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo_v1",
"index_uuid" : "_na_",
"index" : "demo_v1"
},
"status" : 404
}
7.5 创建文档
在此之前demo_v1索引不存在,通过创建文档,自动生成索引,新创建的demo_v1将根据demo_template索引模板生成。
命令:
POST demo_v1/_doc
{
"id": 1,
"title": "这是一条数据"
}
结果:
{
"_index" : "demo_v1",
"_type" : "_doc",
"_id" : "20upIHUBO6Fj2CIJUFPr",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查看数据
GET demo_v1/_search 用索引名称进行查询
GET demo/_search 用别名进行查询
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 2,
"successful" : 2,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "demo_v1",
"_type" : "_doc",
"_id" : "20upIHUBO6Fj2CIJUFPr",
"_score" : 1.0,
"_source" : {
"id" : 1,
"title" : "这是一条数据"
}
}
]
}
}
发现使用索引名称和别名都能搜索出来。但是我们并未单独创建索引别名。我们来查看一下demo_v1索引的结构。
GET demo_v1
{
"demo_v1" : {
"aliases" : {
"demo" : { }
},
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "long"
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "2",
"provided_name" : "demo_v1",
"max_result_window" : "100000",
"creation_date" : "1602570768526",
"number_of_replicas" : "0",
"uuid" : "WrXtDB5eRzmU-xX1vAUCrA",
"version" : {
"created" : "6070099"
}
}
}
}
}
我们可以看到,demo_v1 索引中的数据:
- 分片数(number_of_shards): 2
- 副本(number_of_replicas): 0
- 别名(aliases):demo
- 最大结果窗口(max_result_window):100000
这些都是我们在demo_template模板中设置的,在自动创建索引时,根据索引模板的index_patterns值,只要我们的索引名称是以“demo”为前缀,都会根据该模板生成索引。因此,无论是demo_v1,还是demo_v2,只要是以“demo”为前缀,直接创建文档,如果不存在索引,ES也会自动给我们创建以“demo_template”为模板的索引。实现索引拆分最关键的点,就在于索引模板。
同样,我们通过创建文档,来生成一个没有索引模板的索引进行对比。
查询demo
GET demo/_search
确定demo索引不存在
{
"error" : {
"root_cause" : [
{
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo",
"index_uuid" : "_na_",
"index" : "demo"
}
],
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "demo",
"index_uuid" : "_na_",
"index" : "demo"
},
"status" : 404
}
创建一条文档
POST demo/_doc
{
"id": 1,
"title": "这是一条数据"
}
创建成功
{
"_index" : "demo",
"_type" : "_doc",
"_id" : "PmXEIHUBwM4PCvJbG7Xw",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查看数据
GET demo/_search
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 2,
"successful" : 2,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "demo",
"_type" : "_doc",
"_id" : "PmXEIHUBwM4PCvJbG7Xw",
"_score" : 1.0,
"_source" : {
"id" : 1,
"title" : "这是一条数据"
}
}
]
}
}
数据同步成功,索引也因此创建完成,我们来看看这个索引结构
GET demo
{
"demo" : {
"aliases" : { },
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "long"
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "2",
"provided_name" : "demo",
"creation_date" : "1602572524390",
"number_of_replicas" : "1",
"uuid" : "p8kNddGzQzWOaz5xLcSWhA",
"version" : {
"created" : "6070099"
}
}
}
}
}
我们可以看到,demo索引中的数据:
- 分片数(number_of_shards): 2
- 副本(number_of_replicas): 1
- 别名(aliases):无
- 最大结果窗口(max_result_window):无
为了直观比较,请看下表:
有索引模板(demo_v1) | 无索引模板(demo) | |
---|---|---|
number_of_shards | 2 | 2 |
number_of_replicas | 0 | 1 |
aliases | demo | 无 |
max_result_window | 10w | 无,默认是1w |
上表可知,通过索引模板的创建的索引,有利于我们更好的掌控索引的结构。
通过demo演示,我们可以进一步的理解索引拆分的一个过程及其实现原理,重点在索引模板。
八、参考
收起阅读 »社区日报 第1081期 (2020-10-18)
https://facinating.tech/2020/0 ... tion/
2.MeiliSearch:零配置Elasticsearch。
https://github.com/meilisearch/MeiliSearch
3.现代数据基础的新兴架构。
https://a16z.com/2020/10/15/th ... ture/
编辑:至尊宝
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://facinating.tech/2020/0 ... tion/
2.MeiliSearch:零配置Elasticsearch。
https://github.com/meilisearch/MeiliSearch
3.现代数据基础的新兴架构。
https://a16z.com/2020/10/15/th ... ture/
编辑:至尊宝
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »
社区日报 第1080期 (2020-10-17)
1.简单的自动补全工具(梯子)
https://medium.com/better-programming/create-a-simple-autocomplete-with-elasticsearch-852c47109deb
2.es7的一些新的聚合功能
https://www.elastic.co/cn/blog/aggregate-all-the-things-new-aggregations-in-elasticsearch-7
3.es打分结果查询
https://spoon-elastic.com/all-elastic-search-post/understanding-elastic/scoring-elasticsearch-query/
1.简单的自动补全工具(梯子)
https://medium.com/better-programming/create-a-simple-autocomplete-with-elasticsearch-852c47109deb
2.es7的一些新的聚合功能
https://www.elastic.co/cn/blog/aggregate-all-the-things-new-aggregations-in-elasticsearch-7
3.es打分结果查询
https://spoon-elastic.com/all-elastic-search-post/understanding-elastic/scoring-elasticsearch-query/
收起阅读 »社区日报 第1078期 (2020-10-16)
https://www.slideshare.net/mob ... enges
2,用 Elk 监控 jvm 实践(梯子)
https://www.ashnik.com/using-e ... cale/
3,Elasticsearch 性能调优实践(梯子)
https://medium.com/%40alikzlda ... 4de3c
编辑:江水
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://www.slideshare.net/mob ... enges
2,用 Elk 监控 jvm 实践(梯子)
https://www.ashnik.com/using-e ... cale/
3,Elasticsearch 性能调优实践(梯子)
https://medium.com/%40alikzlda ... 4de3c
编辑:江水
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »
Elastic日报 第1077期 (2020-10-15)
https://mp.weixin.qq.com/s%3F_ ... ab24f
2、Cerebro
https://github.com/lmenezes/cerebro
3、esquery
https://github.com/aquasecurity/esquery
编辑:江水
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://mp.weixin.qq.com/s%3F_ ... ab24f
2、Cerebro
https://github.com/lmenezes/cerebro
3、esquery
https://github.com/aquasecurity/esquery
编辑:江水
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
收起阅读 »
社区日报 第1076期 (2020-10-14)
https://juejin.im/post/6880917345636876301
2、 运用 makelogs 创建合适的 Elasticsearch 测试数据。
https://developer.aliyun.com/article/775323
3、使用Kibana实现热图。
https://logz.io/blog/elk-stack ... tmap/
编辑:叮咚光军
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://juejin.im/post/6880917345636876301
2、 运用 makelogs 创建合适的 Elasticsearch 测试数据。
https://developer.aliyun.com/article/775323
3、使用Kibana实现热图。
https://logz.io/blog/elk-stack ... tmap/
编辑:叮咚光军
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »
社区日报 第1075期 (2020-10-12)
https://www.elastic.co/cn/blog ... earch
2、 es 增量数据同步与无损更新
https://wangbaiyuan.cn/elastic ... .html
3、几个elasticsearch使用经验
https://yuerblog.cc/2018/09/10 ... ence/
编辑:cyberdak
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://www.elastic.co/cn/blog ... earch
2、 es 增量数据同步与无损更新
https://wangbaiyuan.cn/elastic ... .html
3、几个elasticsearch使用经验
https://yuerblog.cc/2018/09/10 ... ence/
编辑:cyberdak
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »
【字节跳动】搜索研发工程师
为公司的企业SaaS服务提供对应搜索中台服务及基础设施,包括但不限于:
1、用最前沿的机器学习算法、海量的数据,做最激动人心的技术、给用户最好的搜索体验;
2、负责搜索服务在线系统架构建设,优化系统稳定性、性能和吞吐量;
3、负责对应数据的索引建设及更新,优化索引数据的一致性及更新效率。
职位要求
1、良好的设计和编码品味,热爱写代码能产出高质量的设计和代码;
2、对稳定性和性能有超乎寻常的关注;
3、熟悉 Linux 操作系统,拥有极强的排查、解决问题(trouble shooting)的能力;
4、熟悉 Lucene、ES 等原理及相关技术,对索引、分词、排序等相关技术有深入的理解;
5、有主流大规模搜索引擎架构和稳定性经验者加分者优先;
6、了解分布式, 有过高并发场景/项目的优化经验者优先;
7、有过搜索中台搭建经验优先
投递:lihaifeng.0314 AT bytedance.com
ps:其他岗位也可以帮忙内推
为公司的企业SaaS服务提供对应搜索中台服务及基础设施,包括但不限于:
1、用最前沿的机器学习算法、海量的数据,做最激动人心的技术、给用户最好的搜索体验;
2、负责搜索服务在线系统架构建设,优化系统稳定性、性能和吞吐量;
3、负责对应数据的索引建设及更新,优化索引数据的一致性及更新效率。
职位要求
1、良好的设计和编码品味,热爱写代码能产出高质量的设计和代码;
2、对稳定性和性能有超乎寻常的关注;
3、熟悉 Linux 操作系统,拥有极强的排查、解决问题(trouble shooting)的能力;
4、熟悉 Lucene、ES 等原理及相关技术,对索引、分词、排序等相关技术有深入的理解;
5、有主流大规模搜索引擎架构和稳定性经验者加分者优先;
6、了解分布式, 有过高并发场景/项目的优化经验者优先;
7、有过搜索中台搭建经验优先
投递:lihaifeng.0314 AT bytedance.com
ps:其他岗位也可以帮忙内推 收起阅读 »
社区日报 第1074期 (2020-09-29)
https://mp.weixin.qq.com/s/837vkN8p75KHLwITnDaF7w
2、 如何将k8日志搬到Elasticsearch上来。
https://computingforgeeks.com/ ... arch/
3、将es索引从生产环境复制到本地docker容器。
https://jolicode.com/blog/how- ... ainer
编辑:叮咚光军
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://mp.weixin.qq.com/s/837vkN8p75KHLwITnDaF7w
2、 如何将k8日志搬到Elasticsearch上来。
https://computingforgeeks.com/ ... arch/
3、将es索引从生产环境复制到本地docker容器。
https://jolicode.com/blog/how- ... ainer
编辑:叮咚光军
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »
社区日报 第1073期 (2020-09-28)
https://zhuanlan.zhihu.com/p/37164734
2.Elasticsearch 之 python 使用
https://www.cnblogs.com/kai-/p/13073632.html
3.小白必看,从入门到实战elasticsearch7.6.1
https://www.cnblogs.com/xiashihua/p/13470664.html
编辑:cyberdak
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://zhuanlan.zhihu.com/p/37164734
2.Elasticsearch 之 python 使用
https://www.cnblogs.com/kai-/p/13073632.html
3.小白必看,从入门到实战elasticsearch7.6.1
https://www.cnblogs.com/xiashihua/p/13470664.html
编辑:cyberdak
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
收起阅读 »
社区日报 第1072期 (2020-09-27)
http://thewindowsupdate.com/20 ... orer/
2.如何使用Elastic search和Kibana探索数据。
https://www.ashnik.com/how-to- ... rt-1/
3.使用Go创建系统图。
https://github.com/blushft/go-diagrams
编辑:至尊宝
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
http://thewindowsupdate.com/20 ... orer/
2.如何使用Elastic search和Kibana探索数据。
https://www.ashnik.com/how-to- ... rt-1/
3.使用Go创建系统图。
https://github.com/blushft/go-diagrams
编辑:至尊宝
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
收起阅读 »
社区日报 第1071期 (2020-09-26)
1.ES安全相关策略
https://spinscale.de/posts/2020-04-07-elasticsearch-securing-a-search-engine-while-maintaining-usability.html
2.rosette es插件
https://github.com/rosette-api/rosette-elasticsearch-plugin
3.如何记录所有的es查询
https://stackoverflow.com/questions/21749997/how-to-log-all-executed-elasticsearch-queries
1.ES安全相关策略
https://spinscale.de/posts/2020-04-07-elasticsearch-securing-a-search-engine-while-maintaining-usability.html
2.rosette es插件
https://github.com/rosette-api/rosette-elasticsearch-plugin
3.如何记录所有的es查询
https://stackoverflow.com/questions/21749997/how-to-log-all-executed-elasticsearch-queries
收起阅读 »社区日报 第1070期 (2020-09-25)
1、Elasticsearch 索引管理最佳实践
https://logz.io/blog/managing- ... ices/
2、Elasticsearch集群规划及性能优化实践
https://cloud.tencent.com/deve ... dabb7
3、比logstash快5倍的 kafka2Elasticsearch 同步工具
https://github.com/tal-tech/go-stash
编辑:铭毅天下
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
1、Elasticsearch 索引管理最佳实践
https://logz.io/blog/managing- ... ices/
2、Elasticsearch集群规划及性能优化实践
https://cloud.tencent.com/deve ... dabb7
3、比logstash快5倍的 kafka2Elasticsearch 同步工具
https://github.com/tal-tech/go-stash
编辑:铭毅天下
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
收起阅读 »
社区日报 第1069期 (2020-09-24)
https://dimmaski.com/ilm-elasticsearch-jaeger/
2.Elasticsearch指南以及排障说明
https://opster.com/elasticsearch-guides/
3.Web administration for Elasticsearch
https://github.com/stephanedio ... admin
编辑:金桥
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup
https://dimmaski.com/ilm-elasticsearch-jaeger/
2.Elasticsearch指南以及排障说明
https://opster.com/elasticsearch-guides/
3.Web administration for Elasticsearch
https://github.com/stephanedio ... admin
编辑:金桥
归档:https://ela.st/cn-daily-all
订阅:https://ela.st/cn-daily-sub
沙龙:https://ela.st/cn-meetup 收起阅读 »