一. 分片
引用自
分片:ES中所有数据的文件块,也是数据的最小单元块
实列场景:假设 IndexA 有2个分片,我们向 IndexA 中插入10条数据 (10个文档),那么这10条数据会尽可能平均的分为5条存储在第一个分片,剩下的5条会存储在另一个分片中。
通常来说一个集群至少有一个节点,一个节点就是一个elasticsearch进程,节点可以有多个索引,索引有多个分片,参考如下图
对于分片更好的理解,下面是引用自某篇博客的理解
单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard(一个index包含多个shard ),分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力
shard分为:
(1)primary shard:主分片
(2)replica shard :备份分片,是primary shard的副本,负责容错,以及承担读请求负载
任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。增减节点时,shard会自动在nodes中负载均衡。
primary shard(建立索引时一次设置,不能修改,默认5个),
replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。
primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改(默认有10个shard,5个primary shard,5个replica shard )
primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上
每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard
下图很形象的表示分片和副本在节点的关系
关于副本节点更详细的解释可以戳这里
二. 倒排索引
对于上图,此时两个文档(数据)都匹配,但是第一个文档比第二个匹配度会更高,如果没有别的条件,这两个数据都会返回
例子:
如果要搜索含有python标签的文章,只需要看标签这一栏,返回对应id即可
三. IK分词器插件
是什么?
分词:把一段中文或者别的划分为一个个的关键字,我们在搜索的时候会把自己的信息进行分词。会把数据库或者索引库的数据进行分词,然后进行匹配,而默认的中文分词将每个字看成一个词,这个时候就需要用到IK分词器
IK分词器提供两个分词算法:ik_smart( 最少切分)和ik_max_word(最细粒度切分)
插件安装
- GitHub上直接拉下来即可
- 将解压后的文件以jk命名放进elasticsearch的plugin的文件夹上即可
最少切分和最细粒度切分对比如下
个人认为,最少切分是满足字典下的最少切分,比如上面的中国共产党,因为中国共产党本身就是字典里的一个词,所以当整个词匹配字典的词之后就不再进行更细的切分
而最细粒度切分,会在每个分好的词中再去找与字典匹配的词,比如,中国共产党这个词满足,因为是最细粒度,所以继续往下拆分,有中国、国共、共产党、共产、党这几个划分
但是当我们搜索一些由用户自己定义的词(字典中没有)的时候,比如 我是搞请不
我们来看看效果
可以看到,无论是最少切片还是最细粒度,搞请不这个词都被分成了三个独立的单词,这是因为字典里没有这样的词
那当有个文章标题为搞请不,又去如何匹配呢?
添加字典词
这个时候我们应该去ik的config目录去配置这个词
我们先去自己写一个dic后缀文件
然后配置文件中引入自己的dic文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
重启后再运行,搞请不就成为一个词了