❶ elasticSearch理论篇—索引、节点、分片
传统我们检索文章,是逐个遍历找到对应关键词的位置;
而倒排索引,是通过分词策略,形成词与文章的映射关系表,这种词典+映射表即为倒排索引。
倒排索引的底层实现是基于:FST(Finite State Transcer)数据结构。
lucene [lu'sen] 从4+版本后开始大量使用的数据结构是FST。FST有两个优点:
利用es的分片预分配。
不能,因为分片数是 文档路由算法 中重要的元素:
shard = hash(routing) % number_of_primary_shards
动态修改分片将意味着几乎重新索引文档数据,这是比仅仅将分片从一个节点复制到另一个节点更重量级的操作。
一个分片存在于单个节点,一个节点可以包含多个分片。
elasticSearch天然具有分布式的特征,实现水平扩容时通过 分片预分配 。在创建索引时,选择合适的分片数。
随着数据量的增加,可以动态的增加节点数,elasticSearch将会自动将分片分配到新增的节点上,当重新分配完成时,每个分片将会有接近至少两倍于之前的运算速度。
elasticSearch中新添加的索引默认被指定了5个主分片。这意味着我们最多可以将那个索引分散到5个节点上,每一个节点一个分片。
不能,一个分片并不是没有代价的。
es适当的预分配是好的,但是上千个分片就有些糟糕。
ElasticSearch推荐的最大JVM堆空间是30~32G, 所以把你的分片最大容量限制为30GB, 然后再对分片数量做合理估算. 例如, 你认为你的数据能达到200GB, 推荐你最多分配7到模瞎8个分片。
在开始阶段, 一个好的方案是根据你的节点数量按照1.5~3倍的原则来创建分片. 例如,如果你有3个节点, 则推荐你创建的分片数最多不超过9(3x3)个。当性能下降时,增加节点,ES会平衡分片的放置。
对于基于日期的索引需求, 并且对索引数据的搜索场景非常少. 也许这些索引量将达到成百上千, 但每个索引的数据量只有1GB甚至更小. 对于这种类似场景, 建议只需要为索引分配1个分片。如日志管理就是一个日期的索引需求,日期索引会很多,但每个索引存放的日志数据量就很少。
副本分片 可以实现高可用。当持有主分片的节点挂掉之后,一个副本分片将会晋升为主分片的角色。
在并码贺索引写入时,副本分片做着和主分片相同的工作。新文档首先被索引进主分片然后在同步到其他所有的副本分片。增加副本分片并不会增加索引容量。
副本分片可以服务于读请求,如果索引偏向查询,那么可以通过增加副本的数目来提升查询性能。但也要为绝派此增加额外的硬件资源。
当使用上面配置时,每一个分片的副本分片数量为1个。
一个拥有两个主分片一份副本的索引可以在四个节点中横向扩展
Elasticsearch: 权威指南 » 数据建模 » 扩容设计 » 扩容的单元
面试官:Elasticsearch如何设计索引?满分答案来了
elasticsearch 设置多少分片合适
新年手打,24道进阶必备Elasticsearch 面试真题(建议收藏!)
❷ 正排索引和倒排索引
倒排索引 (英语:Inverted index),也常被称为 反向索引 、 置入档案 或 反向档案 ,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。
有两种不同的反向索引形式:
一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表。
一个单词的水平反向索引(或者完全反向索引)又包含每个单词在一个文档中的位置。
后者的形式提供了更多的兼容性(比如短语搜索),但是需要更多的时间和空间来创建。
所谓的正排索引是从索引文档到关键词到内容,倒排索引则是相反从关键词到词频,位置,目录等信息,现在通常用于搜索的。由于互联网上的数据量无限大,不可能存储足够多的文档,所以正排索引用处不大。
有两种不同的反向索引形式:
我们就能得到下面的反向文件索引:
对相同的文字,我们得到后面这些完全反向索引,有文档数量和当前查询的单词结果组成的的成对数据。 同样,文档数量和当前查询的单词结果都从零开始。所以, "banana": {(2, 3)} 就是说 "banana"在第三个文档里 ( {displaystyle T_{2}} T_{2}),而且在第三个文档的位置是第四个单词(地址为 3)。
如果我们执行短语搜索"what is it" 我们得到这个短语的全部单词各自的结果所在文档为文档0和文档1。但是这个短语检索的连续的条件仅仅在文档1得到。
反向索引数据结构是典型的搜索引擎检索算法重要的迹差洞部分。
一个搜索引擎执行的目标就是优化查询的速度:找到某个单词在文档中出现的地方。以前,正向索引开发出来用来存储每个文档的单词的列表,接着掉头来开发了一种反向索引。 正向索引的查询往往满足每个文档有序频繁的全文查询和每个单词在校验文档中的验证这样的查询。
实际上,时间、内存、处理器等等资源的限制,技术上正向索引是不能实现的。
为了替代正向索引的每个文档的单词列表,能列出每个查询的单词所有所在文档的列表的反向索引数据结构开发了出来。
随着反向索引的创建,如今的查询能通过立即的单词标示迅速获取结果(经过随机存储)。随机存储也通常被认为快于顺序存储。
索引的构建[4] 相当于从正排表到倒排表的建立过程。当我们分析完网页时 ,得到的是以网页为主码的索引表。当索引建立完成后 ,应得到倒排表 ,具体流程如图所示:
流程描述如下:
1)将文档分析称单词term标记,
2)使用hash去重单词term
3)对单词生成倒排列表
倒排列表就是文档编号DocID,没有包含其他的信息(如词频,单词位置等),这就是姿枯简单的索引。
这个简单索引功能可以用于小数据,例如索引几千个文档。然而它有两点限制:
1)需要有足够的内存来存储倒排表,对于搜索引擎来说, 都是G级别数据,特别是当规模不断扩大时 ,我们根本不可能提供这么多的内存。
2)算法是顺序执行,不便于并行处理。
归并法[4] ,即每次将内存中数据写入磁盘时,包括词典在内的所有中间结果信息都被写入磁盘,这样内存所有内容都可以被清空庆晌,后续建立索引可以使用全部的定额内存。
归并索引
归并索引
如图 归并示意图:
合并流程:
1)页面分析,生成临时倒排数据索引A,B,当临时倒排数据索引A,B占满内存后,将内存索引A,B写入临时文件生成临时倒排文件,
2) 对生成的多个临时倒排文件 ,执行多路归并 ,输出得到最终的倒排文件 ( inverted file)。
合并流程
合并流程
索引创建过程中的页面分析 ,特别是中文分词为主要时间开销。算法的第二步相对很快。这样创建算法的优化集中在中文分词效率上。
❸ 什么是倒排索引
倒排索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件。建立全文索引中有两项非常重要,一个是如何对文本进行分词,一是建立索引的数据结构。分词的方法基本上是二元分词法、最大匹配法和统计方法。索引的数据结构基本上采用倒排索引的结构。
分词的好坏关系到查询的准确程度和生成的索引的大小。在中文分词发展中,早期经常使用分词方式是二元分词法,该方法的基本原理是将包含中文的句子进行二元分割,不考虑单词含义,只对二元单词进行索引。因此该方法所分出的单词数量较多,从而产生的索引数量巨大,查询中会将无用的数据检索出来,好处是算法简单不会漏掉检索的数据。之后又发展出最大匹配分词方法,该方法又分为正向最大分词和逆向最大分词。其原理和查字典类似,对常用单词生成一个词典,分析句子的过程中最大的匹配字典中的单词,从而将句子拆分为有意义的单词链。最大匹配法中正向分词方法对偏正式词语的分辨容易产生错误,比如“首饰和服装”会将“和服”作为单词分出。达梦数据库采用的是改进的逆向最大分词方法,该分词方法较正向正确率有所提高。最为复杂的是通过统计方式进春掘行分词的方法。该方法采用隐式马尔科夫链,也就是后一个单词出现的概率依靠于前一个单词出现的概率,最后统计所有单词出现的概率的最大为分词的依据。这个方法对新名词和地名的识别要远远高于最大匹配法,准确度随着取样文本的数量的增大而提高。
二元分词方法和统计方法是不依赖于词典的,而最大匹配法分词方法是依赖于词典的,词典的内容决定分词结构的好坏。
全文检索的索引被称为倒排索引,之所以成为倒排索引,是因为将每一个单词作为索引项,根据该索引项查找包含该单词的文本。因此,索引都是单词和唯一记录文本的标示是一对多的关系。将索引单词排序,根据排序后的单词定位包含该单词的文本。
步骤1)读取一整条句子到变量str中,转到步骤2
步骤2)从句子的尾端读取1个字到变量word中,转到步骤3
步骤3)在旅森册字典查找word中保存的单词。如果存在则保存word,转到步骤4,否则转到步骤5)
步骤4)如果是字典中拆宏最大单词或者超过最大单词数(认定为新词),从句尾去掉该单词,返回步骤2
步骤5)读取前一个字到word中,构成新单词,转到步骤3)
词库的内存数据结构和词库中单词的匹配算法
内存中单词采用层次结构保存
假设字典中有如下的单词:中国 中华民国 国家 人民 民主
在内存中按照如下方式按层排列,其中每一个方块代表一个字,箭头所指向为该单词的前一个字
❹ Elasticsearch
Elasticsearch是一个基于Lucene的实时分布式的搜索与分析引擎。Elasticsearch为所有类型的数据提供近乎实时的搜索和分析。无论结构化或非结构化文本、数字数据还是地理空间数据,Elasticsearch都可以有效地存储和索引,以支持快速搜索。随着你的数据和查询量的增长,Elasticsearch的分布式特性使部署能够随着它而无缝增长。
Elasticsearch是一个 分布式文档存储 。Elasticsearch不是将信息存储为列式数据行,而是存储已序列化为JSON文档的复杂数据结构。当集群中有多个Elasticsearch节点时,存储的文档会分布在整个集群中,并且可以从任绝掘族何并弊节点立即访问。
存储文档后,它会在近乎实时的情况下被索引并完全可搜索——1秒内。Elasticsearch使用一种称为倒排索引的数据结构,它支持非常快速的全文搜索。倒排索引列出了出现在任何文档中的每个唯一单词,并标识了每个单词出现的所有文档。
索引是文档的优化集合,每个文档都是字段的集合,字段是包含数据的键值对。 默认情况下,Elasticsearch对每个字段中的所有数据进行索引,并且每个索引字段都有一个专用的优化数据结构。
Elasticsearch还具有无预定数据模式(schema-less)的能力,这意味着无需明确指定如何处理文档中可能出现的每个不同字段即可对文档进行索引。启用动态映射后,Elasticsearch会自动检测新字段并将其添加到索引中。只要开始索引文档,Elasticsearch就会检测并将布尔值、浮点和整数值、日期和字符串映射到适当的Elasticsearch数据类型。也可以定义规则来控制动态映射,明确定义映射以完全控制字段的存储和索引方式。
Elasticsearch提供了一个简单REST API,用于管理集群以及索引和搜索数据。可以直接从命令行、应用程序客户端或通过Kibana中的开发者控制台轻松提交请求。
Elasticsearch REST API支持结构化查询、全文查询和将两者结合的复杂查询。结构化查询类似于在SQL中构造的查询类型。全文查询查找与查询字符串匹配的所有文档,并按与搜索词的匹配程度对它们进行排序。
除了搜索单个术语之外,还可以执行短语搜索、相似性搜索和前缀搜索。可以使用 Elasticsearch全面的JSON样式查询语言 (Query DSL) 访问所有这些搜索功能。 您还可以构建SQL样式的查询以在Elasticsearch内本地搜索和聚合数据。
建议使用三个主节点三个数据节点集群,这里是演示
环境规划
Index moles
Index management
可以通过Kibana Management或ILM API创建和管理索引生命周期策略。当您为Beats或Logstash Elasticsearch输出插件启用索引生命周期管理时,默认策略是自动配置的。
索引生命周期阶段共分为五个阶段:
在为日志或指标等时间序列数据编制索引时,不能无限期地写入单个索引。 为了满足索引和搜索性能要求并管理资源使用情况,写入索引直到满足某个阈值,然后创建一个新索引并开始写入它。 使用滚动索引能够达到以下效果:
ILM能够根据索引大小、文档计数或年龄自动滚动到新索引。 当触发 Rollover 时,会创建一个新索引,写入别名会更新为指向新索引,所有后续更新都会写入新索引。散举
索引生命周期操作
配置生命周期策略
启动和停止索引生命周期管理
命令使用均已运行用户执行
elasticsearch-keystore 命令管理 Elasticsearch 密钥库中的安全设置。
elasticsearch-node命令能够在节点上执行某些不安全的操作,这些操作只能在关闭时执行。 此命令允许您调整节点的角色,不安全地编辑集群设置,并且即使在与磁盘上的数据不兼容的情况下,也可以在灾难后恢复某些数据或启动节点。
创建、列出和删除基于文件的服务账户令牌。当创建第一个服务帐户令牌时,此命令会在 $ES_HOME/config 目录中创建一个 service_tokens 文件。 该文件默认不存在。Elasticsearch监视此文件的更改并动态重新加载它.
设置内置用户的密码。此命令仅供在Elasticsearch安全功能的初始配置期间使用。 它使用弹性引导密码来运行用户管理API请求。 如果Elasticsearch密钥库受密码保护,则必须先输入密钥库密码,然后才能为内置用户设置密码。 为弹性用户设置密码后,引导密码不再有效,无法使用该命令。
在某些情况下,分片副本的Lucene索引或事务日志可能会损坏。 elasticsearch-shard命令能够在无法自动恢复或从备份恢复的分片的良好副本时删除分片的损坏部分。运行elasticsearch-shard时,将丢失损坏的数据。在运行elasticsearch-shard之前停止Elasticsearch。
使用基于文件的用户身份验证,则可以使用elasticsearch-users命令添加和删除用户、分配用户角色和管理密码。
参考官方文档 REST APIs
快照是从正在运行的Elasticsearch集群中获取的备份。 可以拍摄整个集群的快照,包括其所有数据流和索引。 还可以仅对集群中的特定数据流或索引进行快照。必须先注册快照存储库,然后才能创建快照。
Elasticsearch以增量方式进行快照:快照过程只将数据复制到存储库中,而之前的快照还没有复制到那里,避免了不必要的重复工作或存储空间。这意味着可以安全地以最小的开销频繁地进行快照。这种增量只适用于单个存储库,因为存储库之间没有数据共享。快照在逻辑上也是相互独立的,即使是在一个存储库内:删除一个快照不会影响任何其他快照的完整性。
可以将快照恢复到正在运行的集群中,默认情况下包括快照中的所有数据流和索引。 也可以选择仅从快照恢复集群状态或特定数据流或索引。
可以使用快照生命周期管理来自动拍摄和管理快照。
快照包含构成索引或数据流支持索引的磁盘上数据结构的副本。这意味着快照只能被恢复到可以读取索引的Elasticsearch版本中。版本兼容图如下:
❺ 索引数据结构都有哪些 分别有什么区别呢 一般都采用什么结构的呢
全文索引、聚集索引、哈希索引、b+树索引等
B+树的简单定义:B+树是为磁盘或其他存储设备设计的一种平衡查找树。B+树中所有记录都是按键值大小顺序存放在叶子节点上,各叶子节点通过指针进行连接。
哈希索引(Hash indexes)采用哈希表来对键值进行查找,时间复杂度为O(1)。
使用哈希索引时对于键值的等值查询是非常快的,但是其他类型的查询如范围查询、模糊查询、排序等是不能使用哈希索引的。这是哈希索引使用比较少的主要原因。
聚集索引(Clustered Index)又称聚簇索引,其叶子节点存放记录。
每个InnoDB 表有一个特定的索引叫做聚集索引,存储行的数据。
如果你的表定义了主键那么主键就是聚集索引,如果没有定义主键,MySQL 会选择第一个非空唯一索引列作为聚集索引,如果表中也没有唯一索引,InnoDB会生成一个类似RowId的隐藏的聚集索引。
全文索引查找条件使用 MATCH AGAINST。
全文索引(Full-text search indexes)使用倒排索引(inverted index)实现。倒排索引会记录文本中的每个关键字出现在文档中的位置。
❻ 什么是倒排牵引正排索引和倒排索引的区别
倒排索引也常被称为反向索引、置入档案或反向档案,被用来存储在全文搜索下某个单词在一个文档或者一组碧段文档中的存储位置的映射。带有倒排索引的文件称为倒排索引文件,简称倒排文件。建立全文索引中有两项非常重要,一运桥个是如何对文本进行分词,一是建立索引的数据结构。分词的方法基本上是二元分词法、最大匹配法和统计方法。索引的数据结构基本上采用倒排索引的结构。
是经过文字,分词,消噪,去重后,索引悔悄誉程序就能够提取关键词,根据分词程序划分好的词,把页面转化为一个关键词组成的集群,同时记录每一个关键词在页面上的出现频率,出现次数,格式,位置,这样,每个页面都能够记录为一串关键词集全,其中每个关键词的词频,格式,位置等权重信息也都记录在案。
一个文件(网站/网页)对应许多关键词
一个关键词对应许多文件(网站/网页)
❼ python倒排索引(Inverted index)
s=raw_input()
lines=s.split(' ')
dictlines=lines[:100]
mydict={}
#read
fori,lineinenumerate(dictlines):
forwordinline.split():
mydict.setdefault(word,[]).append(i+1)
#printindices
forwordinmydict.keys():
print"%s:%s"%(word,",".join(map(str,sorted(mydict[word]))))
defandSearch(words_list):
globalmydict
a=set(range(1,101))
forwordinwords_list:
a=a.intersection(set(mydict[word]))
returna
deforSearch(words_list):
globalmydict
a=set([])
forwordinwords_list:
罩族滚a=a.union(set(mydict[word]))
returna
#Query
index=100
u=lines[index]
whileindex<len(lines):
words_list=u.split()
if":"inu:
ifwords_list[0]=="OR:":
a=orSearch(words_list)
else:
ifwords_list[0]=='AND:':
穗银物余words_list=words_list[1:]
a=andSearch(words_list)
ifnota:
print",".join(map(str,list(a)))
else:
print"None"
index+=1
大致思想就是这样。。。。。。。。