作者:京东保险管顺利
开篇最近使用Elasticsearch实现画像系统,实现的dmp的数据中台能力。同时调研了竞品的架构选型。以及重温了redis原理等。特此做一次es的总结和回顾。网上没看到有人用Elasticsearch来完成画像的。我来做第一次尝试。
背景说完,我们先思考一件事,使用内存系统做数据库。他的优点是什么?他的痛点是什么?
一、原理这里不在阐述全貌。只聊聊通讯、内存、持久化三部分。
通讯es集群最小单元是三个节点。两个从节点搭配保证其高可用也是集群化的基础。那么节点之间RPC通讯用的是什么?必然是netty,es基于netty实现了Netty4Transport的通讯包。初始化Transport后建立Bootstrap,通过MessageChannelHandler完成接收和转发。es里区分server和client,如图1。序列化使用的json。es在rpc设计上偏向于易用、通用、易理解。而不是单追求性能。
有了netty的保驾护航使得es放心是使用json序列化。
内存es内存分为两部分和。onheap这部分由es的jvm管理。offheap则是由lucene管理。onheap被分为两部分,一部分可以回收,一部分不能回收。
能回收的部分indexbuffer存储新的索引文档。当被填满时,缓冲区的文档会被写入到磁盘segment上。node上共享所有shards。
不能被回收的有nodequerycache、shardrequestcache、filedatacache、segmentscache
nodequerycache是node级缓存,过滤后保存在每个node上,被所有shards共享,使用bitset数据结构(布隆优化版)关掉了评分。使用的LRU淘汰策略。GC无法回收。
shardrequestcache是shard级缓存,每个shard都有。默认情况下该缓存只存储request结果size等于0的查询。所以该缓存不会被hits,但却缓存hits.total,aggregations,suggestions。可以通过clearcacheapi清除。使用的LRU淘汰策略。GC无法回收。
filedatacache是把聚合、排序后的data缓存起来。初期es是没有docvalues的,所以聚合、排序后需要有一个filedata来缓存,避免磁盘IO。如果没有足够内存存储filedata,es会不断地从磁盘加载数据到内存,并删除旧的数据。这些会造成磁盘IO和引发GC。所以2.x之后版本引入docvalues特性,把文档构建在indextime上,存储到磁盘,通过memorymappedfile方式访问。甚至如果只关心hits.total,只返回docid,关掉docvalues。docvalues支持keyword和数值类型。text类型还是会创建filedata。
segmentscache是为了加速查询,FST永驻堆内内存。FST可以理解为前缀树,加速查询。but!!es7.3版本开始把FST交给了堆外内存,可以让节点支持更多的数据。FST在磁盘上也有对应的持久化文件。
offheap即SegmentsMemory,堆外内存是给Lucene使用的。所以建议至少留一半的内存给lucene。
es7.3版本开始把tip(termsindex)通过mmp方式加载,交由系统的pagecache管理。除了tip,nvd(norms),dvd(docvalues),tim(termdictionary),cfs(