cse

阅读 / 问答 / 标签

elasticsearch watcher 收费吗

目前还不清楚呢

为什么没有arcsecx?

x的原函数,上面只考虑了x≠0的情况;的图像关于y轴对称;2));=π)x=secy;2)=(x^2-1)^(1/2;(x^2*siny),而y"x是奇函数,那为了方便起见,0<,从y"=x<2)>={1/,所以很多书上都有∫1/(0)=∞又是两码事,我们也不难看出这个导函数中的x应该含有绝对值符号),这与y"在x=0处却不存在;xdx=ln|x|+c。虽然,因为毕竟还是没有对x=0种情况进行讨论.==========================================================================但是;=x<,π/写有绝对值的是严密的;在x=0处没定义,及y"(|x|(x^2-1)^(1/,即y"x,即开方后的数或式子都默认取正号,只能说明y",没有进行特殊说明;=π)x=secy;2)成中心对称,写有绝对值的就是有绝对值,只不过没有写出来罢了(函数y=arcsecx的图像关于(0,简化了推导过程,就把这个极限值当做了函数值(这样做时;(0)不存在,结论简洁明了),所以才会出现有些书上不写绝对值符号(既然x≠0的情况可以不考虑。实际上;x^2)^(1/π/x^(-1)=cosy,作为高等数学来讲;xdx=lnx+c;在x=0处的极限值正好为∞;0这种情况也不考虑了;=0:y"=y<,我们也要理解为∫1/=x<,tgy<2))中:函数y=arcsecx对x=0是有定义的,我想写成这样的书可不多吧;(x*tgy);=0;=1/xdx=lnx+c时,在上面第二种方法中就可以看出,那它的原函数应该是偶函数;x也是成立的;y"=y<2)/=1/=1:-x^(-2)=y",即y",这是不严密的):y"[|x|(x^2-1)^(1/,所以为了确保严密性,干脆连-1<2)当0<2)>(x=0)不写下面一行;是偶函数。其实[ln(-x)]"(当x≠0时)1)当-1<2)),下面的那一行是必不可少的;={1/[x^2*(x^2-1)^(1/,y"=1/(0)=1/x"2))却是奇函数,可以看出,1/y",也不能说是绝对严密的,所以当写为∫1/x<(x(x^2-1)^(1/.x*tgy=x((secy)^2-1)^(1/,也要把它理解为含有绝对值符号;=1/:==================================================y=arcsecx,没写绝对值符号的;=1/y",但是本质是一样的,得;(|x|(x^2-1)^(1/(|x|(x^2-1)^(1/0=∞,所以即便是写成y"。但是;2)=-x(x^2-1)^(1/,0<,π/,这种做法有很多好处;2))在x=0处也就有了定义了;=1/,定义y"2)=x(x^2-1)^(1/x"=0.而siny=(1-(cosy)^2)^(1/=1时,却没有考虑x=0时的情况,也是有漏洞的,微积分就公式推导这一块又不需要太严密(事实上,而lnx是非奇非偶函数;所以y",tgy>2)=(1-1/,应写成;|x|]=1/。再举个关于绝对值的例子;=π?结果的形式太复杂了,是有失严密性的);=1/=x<2)]==================================================y=arcsecx;|x|;(|x|(x^2-1)^(1/=1/,(x≠0)∞,0<2))的形式。即便这样考虑;=0;2)/=y<=1,(-1<0时.x*tgy=-x((secy)^2-1)^(1/:已知(lnx)"。真要说是正确的结论,你看到的那两本书对函数y=arcsecx有两种不同的导函数形式;2<,但是我们在思想上还是应当理解为它是含有绝对值的,避开开方后还要判断正负号的麻烦。此时虽然没写绝对值;y<*(-siny);(x(x^2-1)^(1/,为了简洁起见,而其导数y",(-1<两边求导;(y)=1/所以;=1/那么我们就说lnx是1/,有两种方法可以解释为什么含有绝对值;(y)=secy*tgy=x*tgy

为什么y=arcsecx这个函数会有不同的导函数?

我告诉你原因,y=arcsecx有两种值域,国外教材y的主值是一、三象限,国内教材是一、二象限。即国外教材是[0,π/2)∪(π,3π/2],国内教材是[0,π/2)∪(π/2,π]。很显然定义在一、三象限解题非常简便,因为做不定积分换元法,令x=sect,则tant>0而不需考虑开根号的正负问题

为什么y=arcsecx这个函数会有不同的导函数?

有么?它只有一个导函数 阿

elasticsearch

首先准备环境 ElasticSearch : https://mirrors.huaweicloud.com/elasticsearch/?C=N&O=D logstash : https://mirrors.huaweicloud.com/logstash/?C=N&O=D kibana : https://mirrors.huaweicloud.com/kibana/?C=N&O=D ik : https://github.com/medcl/elasticsearch-analysis-ik/tree/v7.8.0 ElasticSearch 是一个实时分布式搜索和分析引擎,主要用于全文搜索,结构化搜索,分析以及将这三者混合使用。 Lucene 是一个全文检索引擎的架构。 ElasticSearch vs Solr 总结 (1)es基本是开箱即用,非常简单。Solr安装略微复杂一丢丢,可关注( solr6.6教程-基础环境搭建(一) ) (2)Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能。 (3)Solr 支持更多格式的数据,比如JSON、XML、CSV,而 Elasticsearch 仅支持json文件格式。 (4)Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑 (5)Solr 查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用; ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。 Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。 (6)Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而 Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。 ik分词器: ik提供了两个分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度切分。 ik_smart: ik_max_word: ik分词器可以增加自己的配置,自己配置词典。

如何把elasticsearch换成solr架构

从两个方面对ElasticSearch和Solr进行对比,从关系型数据库中的导入速度和模糊查询的速度。单机对比1. Solr 发布了4.0-alpha,试了一下,发现需要自己修改schema,好处是它自带一个data importer。在自己的计算机上测试了一下,导入的性能大概是:14分钟导入 3092730 条记录,约合 3682条/秒。2. 3百万条记录的情况下,模糊查询和排序基本都在1秒内返回3. 刚才的测试,是每个field单独存储,现在修改了一下配置文件,增加了一个copyField,所有的field都拷贝一份到text这个field里面去,导入的性能大概是:19分钟导入了3092730 条记录,约合 2713条/秒4. 3百万条记录的情况下,针对text的模糊查询基本在1秒内返回,但是针对所有记录的排序,大概要2~3秒5. 使用 elasticsearch 0.19.8,缺省配置,用单任务导入,导入性能是:20分钟导入了3092730 条记录,约合2577条/秒6. 3百万条记录的情况下,查询基本上在1秒内返回,但是模糊查询比较慢,第一次要10秒,后来大概要1~3秒。加上排序大概需要5秒,整体排序基本100ms查询及排序的指令:{ "query": { "query_string": { "query": "*999*" } }, "sort": [ { "TIME_UP": { "order": "asc" } } ]}7. Es0.19.8,用两个任务导入,导入性能是:13分钟导入了3092730 条记录,约合3965条/秒8. Solr全部建好索引后,占用磁盘空间是1.2G,es占用磁盘空间是4G单机对比2在一台Intel i7,32G内存的机器上,重新跑这两个的对比。不过有个重大的区别在于,Solr是在这台性能很好的机器上跑,而es的导入进程则是在一台Intel 四核 2.5G,4G内存的机器上跑的,也许会有性能的差异。ES版本0.19.8,Solr版本4.0-ALPHA。1. Solr的导入性能:3400万条记录,用时62分钟,平均9140条/秒,占用空间12.75G2. 使用 *999* 这样的模糊查询,3秒以内返回,稍长一点的查询条件 *00100014*,也是2~3秒返回3. Es的导入性能(设置Xmx为10G):3400万条记录,用时40分钟,平均14167条/秒,占用空间33.26G,客户端采用4个并发。4. 使用 *999* 这样的模糊查询,9秒返回,稍长一点的查询条件 *00100014*,11.8秒返回5. 如果不是针对所有字段查询,而是针对某个特定字段,比如 SAM_CODE: *00100014*,那么也是1秒以内返回。6. 结论:es的查询效率也可以很高,只是我们还不会用。7. 结论2:es有个设置是把所有字段放一块的那个,缺省是放一起,但是不知道为什么没起到应有的作用。备注:1. Solr第一次的那个内存使用的是缺省设置,这次改为10G,结果导入性能反而变差了,400万条记录,用了8分钟,平均8333条/秒,不知道为什么。2. 改回缺省的内存配置,导入速度仍然慢。3. 重启Linux,用10G的内存配置,再导入,5030万条记录,用时92分,约9112条/秒,说明导入速度和内存配置没有大差别4. 在10G配置的情况下,检索速度也差别不大。5. 为了搞清楚lucene4.0和solr4.0的进步有多大,下载了solr3.6.1,所幸的是4.0的配置文件在3.6.1上也可以用,所以很快就搭起来进行测试,导入性能为:3400万条记录,用时55分钟,约10303条/秒,占用空间13.85G。查询性能:*999*第一次11.6s,*00100014* 27.3s,相比4.0ALPHA的结果(5000万结果当中,*999*第一次2.6s,*00100014*第一次2.5s)来说,慢了很多,与es的性能差不多,因此,也许lucene4.0真的对性能有大幅提升?集群对比:采用4台同样配置(Intel i7,32G内存)的Centos 6.3组成的集群,进行对比。1. 首先是es,很方便的就组成了一个Cluster,等上一个3400万条的Index全部均衡负载之后进行测试,导入到另外一个Index当中。2. 导入性能:8500万条记录,用时72分钟,约为19676条/秒。在前5千万条记录导入时的速度在2万/条以上,初始的速度在2.2万/条。占用空间78.6G(由于有冗余,实际占用空间为157.2G)3. 查询性能:*999*第一次13.5秒,第二次19.5秒,第三次7.4秒,第四次7.1秒,第五次7.1秒*00100014*第一次17.2秒,第二次16.6秒,第三次17.9秒,第四次16.7秒,第五次17.1秒SAM_CODE:*999*,0.8s,1.3s,0.02s,0.02s,0.02sSAM_CODE: *00100014*,0.1s,0.1s,0.02s,0.03s,0.05s4. Solr4.0-ALPHA,SolrCloud的配置还算简单,启动一个ZooKeeper,然后其他三台机器访问这个地址,就可以组成一个Cloud:机器1: nohup java -Xms10G -Xmx10G -Xss256k -Djetty.port=8983 -Dsolr.solr.home="./example-DIH/solr/" -Dbootstrap_confdir=./example-DIH/solr/db/conf/ -Dcollection.configName=xabconf3 -DzkRun -DnumShards=4 -jar start.jar &其他机器:nohup java -Xms10G -Xmx10G -Dsolr.solr.home="./example-DIH/solr/" -DzkHost=192.168.2.11:9983 -jar start.jar &但是在执行 data import 的时候,频繁出现 OutOfMemoryError: unable to create new native thread。查了很多资料,把Linux的ulimit当中的nproc改成10240,把Xss改成256K,都解决不了问题。暂时没有办法进行。结论1. 导入性能,es更强2. 查询性能,solr 4.0最好,es与solr 3.6持平,可以乐观的认为,等es采用了lucene4之后,性能会有质的提升3. Es采用SAM_CODE这样的查询性能很好,但是用_all性能就很差,而且差别非常大,因此,个人认为在目前的es情况下,仍然有性能提升的空间,只是现在还没找到方法。

elasticsearch,solr对比各自有哪些优缺点

从两个方面对ElasticSearch和Solr进行对比,从关系型数据库中的导入速度和模糊查询的速度。单机对比1. Solr 发布了4.0-alpha,试了一下,发现需要自己修改schema,好处是它自带一个data importer。在自己的计算机上测试了一下,导入的性能大概是:14分钟导入 3092730 条记录,约合 3682条/秒。2. 3百万条记录的情况下,模糊查询和排序基本都在1秒内返回3. 刚才的测试,是每个field单独存储,现在修改了一下配置文件,增加了一个copyField,所有的field都拷贝一份到text这个field里面去,导入的性能大概是:19分钟导入了3092730 条记录,约合 2713条/秒4. 3百万条记录的情况下,针对text的模糊查询基本在1秒内返回,但是针对所有记录的排序,大概要2~3秒5. 使用 elasticsearch 0.19.8,缺省配置,用单任务导入,导入性能是:20分钟导入了3092730 条记录,约合2577条/秒6. 3百万条记录的情况下,查询基本上在1秒内返回,但是模糊查询比较慢,第一次要10秒,后来大概要1~3秒。加上排序大概需要5秒,整体排序基本100ms查询及排序的指令:{ "query": { "query_string": { "query": "*999*" } }, "sort": [ { "TIME_UP": { "order": "asc" } } ]}7. Es0.19.8,用两个任务导入,导入性能是:13分钟导入了3092730 条记录,约合3965条/秒8. Solr全部建好索引后,占用磁盘空间是1.2G,es占用磁盘空间是4G单机对比2在一台Intel i7,32G内存的机器上,重新跑这两个的对比。不过有个重大的区别在于,Solr是在这台性能很好的机器上跑,而es的导入进程则是在一台Intel 四核 2.5G,4G内存的机器上跑的,也许会有性能的差异。ES版本0.19.8,Solr版本4.0-ALPHA。1. Solr的导入性能:3400万条记录,用时62分钟,平均9140条/秒,占用空间12.75G2. 使用 *999* 这样的模糊查询,3秒以内返回,稍长一点的查询条件 *00100014*,也是2~3秒返回3. Es的导入性能(设置Xmx为10G):3400万条记录,用时40分钟,平均14167条/秒,占用空间33.26G,客户端采用4个并发。4. 使用 *999* 这样的模糊查询,9秒返回,稍长一点的查询条件 *00100014*,11.8秒返回5. 如果不是针对所有字段查询,而是针对某个特定字段,比如 SAM_CODE: *00100014*,那么也是1秒以内返回。6. 结论:es的查询效率也可以很高,只是我们还不会用。7. 结论2:es有个设置是把所有字段放一块的那个,缺省是放一起,但是不知道为什么没起到应有的作用。备注:1. Solr第一次的那个内存使用的是缺省设置,这次改为10G,结果导入性能反而变差了,400万条记录,用了8分钟,平均8333条/秒,不知道为什么。2. 改回缺省的内存配置,导入速度仍然慢。3. 重启Linux,用10G的内存配置,再导入,5030万条记录,用时92分,约9112条/秒,说明导入速度和内存配置没有大差别4. 在10G配置的情况下,检索速度也差别不大。5. 为了搞清楚lucene4.0和solr4.0的进步有多大,下载了solr3.6.1,所幸的是4.0的配置文件在3.6.1上也可以用,所以很快就搭起来进行测试,导入性能为:3400万条记录,用时55分钟,约10303条/秒,占用空间13.85G。查询性能:*999*第一次11.6s,*00100014* 27.3s,相比4.0ALPHA的结果(5000万结果当中,*999*第一次2.6s,*00100014*第一次2.5s)来说,慢了很多,与es的性能差不多,因此,也许lucene4.0真的对性能有大幅提升?集群对比:采用4台同样配置(Intel i7,32G内存)的Centos 6.3组成的集群,进行对比。1. 首先是es,很方便的就组成了一个Cluster,等上一个3400万条的Index全部均衡负载之后进行测试,导入到另外一个Index当中。2. 导入性能:8500万条记录,用时72分钟,约为19676条/秒。在前5千万条记录导入时的速度在2万/条以上,初始的速度在2.2万/条。占用空间78.6G(由于有冗余,实际占用空间为157.2G)3. 查询性能:*999*第一次13.5秒,第二次19.5秒,第三次7.4秒,第四次7.1秒,第五次7.1秒*00100014*第一次17.2秒,第二次16.6秒,第三次17.9秒,第四次16.7秒,第五次17.1秒SAM_CODE:*999*,0.8s,1.3s,0.02s,0.02s,0.02sSAM_CODE: *00100014*,0.1s,0.1s,0.02s,0.03s,0.05s4. Solr4.0-ALPHA,SolrCloud的配置还算简单,启动一个ZooKeeper,然后其他三台机器访问这个地址,就可以组成一个Cloud:机器1: nohup java -Xms10G -Xmx10G -Xss256k -Djetty.port=8983 -Dsolr.solr.home="./example-DIH/solr/" -Dbootstrap_confdir=./example-DIH/solr/db/conf/ -Dcollection.configName=xabconf3 -DzkRun -DnumShards=4 -jar start.jar &其他机器:nohup java -Xms10G -Xmx10G -Dsolr.solr.home="./example-DIH/solr/" -DzkHost=192.168.2.11:9983 -jar start.jar &但是在执行 data import 的时候,频繁出现 OutOfMemoryError: unable to create new native thread。查了很多资料,把Linux的ulimit当中的nproc改成10240,把Xss改成256K,都解决不了问题。暂时没有办法进行。结论1. 导入性能,es更强2. 查询性能,solr 4.0最好,es与solr 3.6持平,可以乐观的认为,等es采用了lucene4之后,性能会有质的提升3. Es采用SAM_CODE这样的查询性能很好,但是用_all性能就很差,而且差别非常大,因此,个人认为在目前的es情况下,仍然有性能提升的空间,只是现在还没找到方法。

PB级大规模Elasticsearch集群运维与调优实践

某中型互联网公司的游戏业务,使用了腾讯云的Elasticsearch产品,采用ELK架构存储业务日志。因为游戏业务本身的日志数据量非常大(写入峰值在100w qps),在服务客户的几个月中,踩了不少坑,经过数次优化与调整,把客户的ES集群调整的比较稳定,避免了在业务高峰时客户集群的读写异常,并且降低了客户的资金成本和使用成本。下面把服务客户过程中遇到的典型问题进行梳理,总结经验,避免再次踩坑。 解决方案架构师A: bellen, XX要上线一款新游戏,日志存储决定用ELK架构,他们决定在XX云和我们之间二选一,我们首先去他们公司和他们交流一下,争取拿下! bellen: 好,随时有空! 。。。 和架构师一起前往该公司,跟负责底层组件的运维部门的负责人进行沟通。 XX公司运维老大:不要讲你们的PPT了,先告诉我你们能给我们带来什么! bellen: 。。。呃,我们有很多优势。。。比如灵活地扩容缩容集群,还可以一键平滑升级集群版本,并且提供有跨机房容灾的集群从而实现高可用。。 XX公司运维老大:你说的这些别的厂商也有,我就问一个问题,我们现在要存储一年的游戏日志,不能删除数据,每天就按10TB的数据量算,一年也得有个3PB多的数据,这么大的数量,都放在SSD云盘上,我们的成本太高了,你们有什么方案既能够满足我们存储这么大数据量的需求,同时能够降低我们的成本吗? bellen: 我们本身提供的有冷热模式的集群,热节点采用SSD云硬盘,冷节点采用SATA盘,采用ES自带的ILM索引生命周期管理功能定期把较老的索引从热节点迁移到冷节点上,这样从整体上可以降低成本。另外一方面,也可以定期把更老的索引通过snapshot快照备份到COS对象存储中,然后删除索引,这样成本就更低了。 XX公司运维老大:存储到COS就是冷存储呗,我们需要查询COS里的数据时,还得再把数据恢复到ES里?这样不行,速度太慢了,业务等不了那么长时间,我们的数据不能删除,只能放在ES里!你们能不能给我们提供一个API, 让老的索引数据虽然存储在COS里,但是通过这个API依然可以查询到数据,而不是先恢复到ES, 再进行查询? bellen: 。。。呃,这个可以做,但是需要时间。是否可以采用hadoop on COS的架构,把存量的老的索引数据通过工具导入到COS,通过hive去查询,这样成本会非常低,数据依然是随时可查的。 XX公司运维老大:那不行,我们只想用成熟的ELK架构来做,再增加hadoop那一套东西,我们没那么多人力搞这个事! bellen: 好吧,那可以先搞一个集群测试起来,看看性能怎么样。关于存量数据放在COS里但是也需要查询的问题,我们可以先制定方案,尽快实施起来。 XX公司运维老大:行吧,我们现在按每天10TB数据量预估,先购买一个集群,能撑3个月的数据量就行,能给一个集群配置的建议吗? bellen: 目前支持单节点磁盘最大6TB, cpu和内存的话可以放到8核32G单节点,单节点跑2w qps写入没有问题,后面也可以进行纵向扩容和横向扩容。 XX公司运维老大:好,我们先测试一下。 N 天后,架构师A直接在微信群里反馈:"bellen, 客户反馈这边的ES集群性能不行啊,使用logstash消费kafka中的日志数据,跑了快一天了数据还没追平,这是线上的集群,麻烦紧急看一下吧。。" 我一看,一脸懵, 什么时候已经上线了啊,不是还在测试中吗? XX公司运维小B: 我们购买了8核32G*10节点的集群,单节点磁盘6TB, 索引设置的10分片1副本,现在使用logstash消费kafka中的数据,一直没有追平,kafka中还有很多数据积压,感觉是ES的写入性能有问题。 随后我立即查看了集群的监控数据,发现cpu和load都很高,jvm堆内存使用率平均都到了90%,节点jvm gc非常频繁了,部分节点因为响应缓慢,不停的离线又上线。。 经过沟通,发现用户的使用姿势是filebeat+kafka+logstash+elasticsearch, 当前已经在kafka中存储了有10天的日志数据,启动了20台logstash进行消费,logstash的batch size也调到了5000,性能瓶颈是在ES这一侧。客户8核32G*10节点的集群,理论上跑10w qps没有问题,但是logstash消费积压的数据往ES写入的qps远不止10w,所以是ES扛不住写入压力了,所以只能对ES集群进行扩容,为了加快存量数据的消费速度,先纵向扩容单节点的配置到32核64GB,之后再横向增加节点,以保证ES集群能够最大支持100w qps的写入(这里需要注意的是,增加节点后索引的分片数量也需要调整)。 所以一般新客户接入使用ES时,必须要事先评估好节点配置和集群规模,可以从以下几个方面进行评估: 上述场景2遇到的问题是业务上线前没有对集群配置和规模进行合理的评估,导致上线后ES集群负载就很高,通过合理的扩容处理,集群最终抗住了写入压力。但是又有新的问题出现了。 因为kafka积压的数据比较多,客户使用logstash消费kafka数据时,反馈有两个问题: 经过分析客户logstash的配置文件,发现问题出现的原因主要是: 分析后,对kafka和logstash进行了如下优化: 通过上述优化,最终使得logstash机器资源都被充分利用上,很快消费完堆积的kafka数据,待消费速度追平生成速度后,logstash消费kafka一直稳定运行,没有出现积压。 另外,客户一开始使用的是5.6.4版本的logstash,版本较老,使用过程中出现因为单个消息体过长导致logstash抛异常后直接退出的问题: 通过把logstash升级至高版本6.8避免了这个问题(6.x版本的logstash修复了这个问题,避免了crash)。 客户的游戏上线有一个月了,原先预估每天最多有10TB的数据量,实际则是在运营活动期间每天产生20TB的数据,原先6TB*60=360TB总量的数据盘使用率也达到了80%。针对这种情况,我们建议客户使用冷热分离的集群架构,在原先60个热节点的基础上,增加一批warm节点存储冷数据,利用ILM(索引生命周期管理)功能定期迁移热节点上的索引到warm节点上。 通过增加warm节点的方式,客户的集群磁盘总量达到了780TB, 可以满足最多三个月的存储需求。但是客户的需求还没有满足: XX公司运维老大:给我们一个能存放一年数据的方案吧,总是通过加节点扩容磁盘的方式不是长久之计,我们得天天盯着这个集群,运维成本很高!并且一直加节点,ES会扛不住吧? bellen: 可以尝试使用我们新上线的支持本地盘的机型,热节点最大支持7.2TB的本地SSD盘,warm节点最大支持48TB的本地SATA盘。一方面热节点的性能相比云盘提高了,另外warm节点可以支持更大的磁盘容量。单节点可以支持的磁盘容量增大了,节点数量就不用太多了,可以避免踩到因为节点数量太多而触发的坑。 XX公司运维老大:现在用的是云盘,能替换成本地盘吗,怎么替换? bellen: 不能直接替换,需要在集群中新加入带本地盘的节点,把数据从老的云盘节点迁移到新的节点上,迁移完成后再剔除掉旧的节点,这样可以保证服务不会中断,读写都可以正常进行。 XX公司运维老大:好,可以实施,尽快搞起来! 云盘切换为本地盘,是通过调用云服务后台的API自动实施的。在实施之后,触发了数据从旧节点迁移到新节点的流程,但是大约半个小时候,问题又出现了: XX公司运维小B: bellen, 快看一下,ES的写入快掉0了。 bellen: 。。。 通过查看集群监控,发现写入qps直接由50w降到1w,写入拒绝率猛增,通过查看集群日志,发现是因为当前小时的索引没有创建成功导致写入失败。 紧急情况下,执行了以下操作定位到了原因: 经过了这次扩容操作,总结了如下经验: 在稳定运行了一阵后,集群又出问题了。。 XX公司运维小B: bellen, 昨晚凌晨1点钟之后,集群就没有写入了,现在kafka里有大量的数据堆积,麻烦尽快看一下? bellen: 。。。 通过cerebro查看集群,发现集群处于yellow状态,然后发现集群有大量的错误日志: 然后再进一步查看集群日志,发现有"master not discovered yet..."之类的错误日志,检查三个master节点,发现有两个master挂掉,只剩一个了,集群无法选主。 登陆到挂了了master节点机器上,发现保活程序无法启动es进程,第一直觉是es进程oom了;此时也发现master节点磁盘使用率100%, 检查了JVM堆内存快照文件目录,发现有大量的快照文件,于是删除了一部分文件,重启es进程,进程正常启动了;但是问题是堆内存使用率太高,gc非常频繁,master节点响应非常慢,大量的创建索引的任务都超时,阻塞在任务队列中,集群还是无法恢复正常。 看到集群master节点的配置是16核32GB内存,JVM实际只分配了16GB内存,此时只好通过对master节点原地增加内存到64GB(虚拟机,使用的腾讯云CVM, 可以调整机器规格,需要重启),master节点机器重启之后,修改了es目录jvm.options文件,调整了堆内存大小,重新启动了es进程。 3个master节点都恢复正常了,但是分片还需要进行恢复,通过GET _cluster/health看到集群当前有超过10w个分片,而这些分片恢复还需要一段时间,通过调大"cluster.routing.allocation.node_concurrent_recoveries", 增大分片恢复的并发数量。实际上5w个主分片恢复的是比较快的了,但是副本分片的恢复就相对慢很多,因为部分副本分片需要从主分片上同步数据才能恢复。此时可以采取的方式是把部分旧的索引副本数量调为0, 让大量副本分片恢复的任务尽快结束,保证新索引能够正常创建,从而使得集群能够正常写入。 总结这次故障的根本原因是集群的索引和分片数量太多,集群元数据占用了大量的堆内存,而master节点本身的JVM内存只有16GB(数据节点有32GB), master节点频繁full gc导致master节点异常,从而最终导致整个集群异常。所以要解决这个问题,还是得从根本上解决集群的分片数量过多的问题。 目前日志索引是按照小时创建,60分片1副本,每天有24*60*2=2880个分片,每个月就产生86400个分片,这么多的分片可能会带来严重的问题。有以下几种方式解决分片数量过多的问题: 和客户沟通过后,客户表示可以接受方式1和方式2,但是方式3和4不能接受,因为考虑到存在磁盘故障的可能性,必须保留一个副本来保证数据的可靠性;另外还必须保证所有数据都是随时可查询的,不能关闭。 在场景5中,虽然通过临时给master节点增加内存,抗住了10w分片,但是不能从根本上解决问题。客户的数据是计划保留一年的,如果不进行优化,集群必然扛不住数十万个分片。所以接下来需要着重解决集群整体分片数量过多的问题,在场景5的最后提到了,用户可以接受开启shrink以及降低索引创建粒度(经过调整后,每两个小时创建一个索引),这在一定程度上减少了分片的数量,能够使集群暂时稳定一阵。 辅助客户在kibana上配置了如下的ILM策略: 在warm phase, 把创建时间超过360小时的索引从hot节点迁移到warm节点上,保持索引的副本数量为1,之所以使用360小时作为条件,而不是15天作为条件,是因为客户的索引是按小时创建的,如果以15天作为迁移条件,则在每天凌晨都会同时触发15天前的24个索引一共24*120=2880个分片同时开始迁移索引,容易引发场景4中介绍的由于迁移分片数量过多导致创建索引被阻塞的问题,所以以360小时作为条件,则在每个小时只会执行一个索引的迁移,这样把24个索引的迁移任务打平,避免其它任务被阻塞的情况发生。 同时,也在warm phase阶段,设置索引shrink,把索引的分片数缩成5个,因为老的索引已经不执行写入了,所以也可以执行force merge, 强制把segment文件合并为1个,可以获得更好的查询性能。 另外,设置了ILM策略后,可以在索引模板里增加index.lifecycle.name配置,使得所有新创建的索引都可以和新添加的ILM策略关联,从而使得ILM能够正常运行。 客户使用的ES版本是6.8.2, 在运行ILM的过程中, 也发现一些问题: 这是因为shrink操作需要新把索引完整的一份数据都迁移到一个节点上,然后在内存中构建新的分片元数据,把新的分片通过软链接指向到几个老的分片的数据,在ILM中执行shrink时,ILM会对索引进行如下配置: 问题是索引包含副本,而主分片和副本分片又不能在同一个节点上,所以会出现部分分片无法分配的情况(不是全部,只有一部分),这里应该是触发了6.8版本的ILM的bug,需要查看源码才能定位解决这个bug,目前还在研究中。当前的workaround是通过脚本定期扫描出现unassigned shards的索引,修改其settings: 优先保证分片先从hot节点迁移到warm节点,这样后续的shrink才能顺利执行(也可能执行失败,因为60个分片都在一个节点上,可能会触发rebalance, 导致分片迁移走,shrink的前置条件又不满足,导致执行失败)。要完全规避这个问题,还得在ILM策略中设置,满足创建时间超过360个小时的索引,副本直接调整为0,但是客户又不接受,没办法。 在场景5和6中,介绍了10w个分片会给集群带来的影响和通过开启shrink来降低分片数量,但是仍然有两个需要重点解决的问题: 可以估算一下,按小时建索引,60分片1副本,一年的分片数为24*120*365=1051200个分片,执行shrink后分片数量24*10*350 + 24*120*15 = 127200(15天内的新索引为了保障写入性能和数据可靠性,仍然保持60分片1副本,旧的索引shrink为5分片1副本), 仍然有超过10w个分片。结合集群一年总的存储量和单个分片可以支持的数据量大小进行评估,我们期望集群总体的分片数量可以稳定为6w~8w,怎么优化? 可以想到的方案是执行数据冷备份,把比较老的索引都冷备到其它的存储介质上比如HDFS,S3,腾讯云的COS对象存储等,但是问题是这些冷备的数据如果也要查询,需要先恢复到ES中才可查,恢复速度比较慢,客户无法接受。由此也产生了新的想法,目前老的索引仍然是1副本,可以把老索引先进行冷备份,再把副本调为0,这样做有以下几点好处: 经过和客户沟通,客户接受了上述方案,计划把老索引冷备到腾讯云的对象存储COS中,实施步骤为: 其中步骤1的实施可以通过脚本实现,本案例中采用腾讯云SCF云函数进行实施,方便快捷可监控。实施要点有: 在实施完步骤1之后,就可以批量把对索引进行过备份的索引副本数都调为0, 这样一次性释放了很多磁盘空间,并且显著降低了集群整体的分片数量。 接下来实施步骤2,需要每天执行一次快照,多创建时间较久的索引进行备份,实施比较简单,可以通过crontab定时执行脚本或者使用腾讯云SCF执行。 步骤2实施之后,就可以修改ILM策略,开启cold phase, 修改索引副本数量为0: 此处的timing是创建时间20天后,需要保证步骤2中对过去老索引数据备份先执行完成才可以进入到cold phase. 通过老索引数据冷备并且降低索引副本,我们可以把集群整体的分片数量维持在一个较低的水位,但是还有另外一个问题待解决,也即shrink失败的问题。刚好,我们可以利用对老索引数据冷备并且降低索引副本的方案,来彻底解决shrink失败的问题。 在场景5中有提到,shrink失败归根接地是因为索引的副本数量为1, 现在我们可以吧数据备份和降低副本提前,让老索引进入到ILM的warm phase中时已经是0副本,之后再执行shrink操作就不会有问题了;同时,因为副本降低了,索引从hot节点迁移到warm节点迁移的数据量也减少了一半,从而降低了集群负载,一举两得。 因此,我们需要修改ILM策略,在warm phase就把索引的副本数量调整为0, 然后去除cold phase。 另外一个可选的优化项是,对老的索引进行冻结,冻结索引是指把索引常驻内存的一些数据从内存中清理掉(比如FST, 元数据等), 从而降低内存使用量,而在查询已经冻结的索引时,会重新构建出临时的索引数据结构存放在内存中,查询完毕再清理掉;需要注意的是,默认情况下是无法查询已经冻结的索引的,需要在查询时显式的增加"ignore_throttled=false"参数。 经过上述优化,我们最终解决了集群整体分片数量过多和shrink失败的问题。在实施过程中引入了额外的定时任务脚本实施自动化快照,实际上在7.4版本的ES中,已经有这个功能了,特性名称为 SLM (快照生命周期管理),并且可以结合ILM使用,在ILM中增加了"wait_for_snapshot"的ACTION, 但是却只能在delete phase中使用,不满足我们的场景。 在上述的场景4-7中,我们花费大量的精力去解决问题和优化使用方式,保证ES集群能够稳定运行,支持PB级别的存储。溯本回原,如果我们能有一个方案使得客户只需要把热数据放在SSD盘上,然后冷数据存储到COS/S3上,但同时又使冷数据能够支持按需随时可查,那我们前面碰到的所有问题都迎刃而解了。可以想象得到的好处有: 而这正是目前es开源社区正在开发中的Searchable Snapshots功能,从 Searchable Snapshots API 的官方文档上可以看到,我们可以创建一个索引,将其挂载到一个指定的快照中,这个新的索引是可查询的,虽然查询时间可能会慢点,但是在日志场景中,对一些较老的索引进行查询时,延迟大点一般都是可以接受的。 所以我认为,Searchable Snapshots解决了很多痛点,将会给ES带了新的繁荣! 经历过上述运维和优化ES集群的实践,我们总结到的经验有: 从一开始和客户进行接触,了解客户诉求,逐步解决ES集群的问题,最终使得ES集群能够保持稳定,这中间的经历让我真真正正的领悟到"实践出真知",只有不断实践,才能对异常情况迅速做出反应,以及对客户提的优化需求迅速反馈。

tan arcsecx

求tany 的值而y是x的反余割值

t=arcsec2/x tant=?求解一道数学题

分情况讨论,x=0时,t是90度,其他情况下用公式表示。。。

x=asect,t为什么不等于arcsec t的值应该怎么求能详细推算一下吗(对于arc不是很了解)

x= asectsect =x/at=arcsec(x/a) = arccos(a/x)

Elasticsearch性能优化

注:文本整理自《ELKstack权威指南》 在 CRUD 章节,我们已经知道 ES 的数据写入是如何操作的了。喜欢自己动手的读者可能已经迫不及待的自己写了程序开始往 ES 里写数据做测试。这时候大家会发现:程序的运行速度非常一般,即使 ES 服务运行在本机,一秒钟大概也就能写入几百条数据。 这种速度显然不是 ES 的极限。事实上,每条数据经过一次完整的 HTTP POST 请求和 ES indexing 是一种极大的性能浪费,为此,ES 设计了批量提交方式。在数据读取方面,叫 mget 接口,在数据变更方面,叫 bulk 接口。mget 一般常用于搜索时 ES 节点之间批量获取中间结果集,对于 Elastic Stack 用户,更常见到的是 bulk 接口。 bulk 接口采用一种比较简朴的数据积累格式,示例如下: 格式是,每条 JSON 数据的上面,加一行描述性的元 JSON,指明下一行数据的操作类型,归属索引信息等。 采用这种格式,而不是一般的 JSON 数组格式,是因为接收到 bulk 请求的 ES 节点,就可以不需要做完整的 JSON 数组解析处理,直接按行处理简短的元 JSON,就可以确定下一行数据 JSON 转发给哪个数据节点了。这样,一个固定内存大小的 network buffer 空间,就可以反复使用,又节省了大量 JVM 的 GC。 事实上,产品级的 logstash、rsyslog、spark 都是默认采用 bulk 接口进行数据写入的。对于打算自己写程序的读者,建议采用 Perl 的 Search::Elasticsearch::Bulk 或者 Python 的 elasticsearch.helpers.* 库。 在配置 bulk 数据的时候,一般需要注意的就是请求体大小(bulk size)。 这里有一点细节上的矛盾,我们知道,HTTP 请求,是可以通过 HTTP 状态码 100 Continue 来持续发送数据的。但对于 ES 节点接收 HTTP 请求体的 Content-Length 来说,是按照整个大小来计算的。所以,首先,要确保 bulk 数据不要超过 http.max_content_length 设置。 那么,是不是尽量让 bulk size 接近这个数值呢?当然不是。 依然是请求体的问题,因为请求体需要全部加载到内存,而 JVM Heap 一共就那么多(按 31GB 算),过大的请求体,会挤占其他线程池的空间,反而导致写入性能的下降。 再考虑网卡流量,磁盘转速的问题,所以一般来说,建议 bulk 请求体的大小,在 15MB 左右,通过实际测试继续向上探索最合适的设置。 注意:这里说的 15MB 是请求体的字节数,而不是程序里里设置的 bulk size。bulk size 一般指数据的条目数。不要忘了,bulk 请求体中,每条数据还会额外带上一行元 JSON。 以 logstash 默认的 bulk_size => 5000 为例,假设单条数据平均大小 200B ,一次 bulk 请求体的大小就是 1.5MB。那么我们可以尝试 bulk_size => 50000 ;而如果单条数据平均大小是 20KB,一次 bulk 大小就是 100MB,显然超标了,需要尝试下调至 bulk_size => 500 。 gateway 是 ES 设计用来长期存储索引数据的接口。一般来说,大家都是用本地磁盘来存储索引数据,即 gateway.type 为 local 。 数据恢复中,有很多策略调整我们已经在之前分片控制小节讲过。除开分片级别的控制以外,gateway 级别也还有一些可优化的地方: 注意:gateway 中说的节点,仅包括主节点和数据节点,纯粹的 client 节点是不算在内的。如果你有更明确的选择,也可以按需求写: 虽然 ES 对 gateway 使用 NFS,iscsi 等共享存储的方式极力反对,但是对于较大量级的索引的副本数据,ES 从 1.5 版本开始,还是提供了一种节约成本又不特别影响性能的方式:影子副本(shadow replica)。 首先,需要在集群各节点的 elasticsearch.yml 中开启选项: 同时,确保各节点使用相同的路径挂载了共享存储,且目录权限为 Elasticsearch 进程用户可读可写。 然后,创建索引: 针对 shadow replicas ,ES 节点不会做实际的索引操作,而是单纯的每次 flush 时,把 segment 内容 fsync 到共享存储磁盘上。然后 refresh 让其他节点能够搜索该 segment 内容。 如果你已经决定把数据放到共享存储上了,采用 shadow replicas 还是有一些好处的: 但是请注意:主分片节点还是要承担一个副本的写入过程,并不像 Lucene 的 FileReplicator 那样通过复制文件完成,所以达不到完全节省 CPU 的效果。 shadow replicas 只是一个在某些特定环境下有用的方式。在资源允许的情况下,还是应该使用 local gateway。而另外采用 snapshot 接口来完成数据长期备份到 HDFS 或其他共享存储的需要。 我们都知道,ES 中的 master 跟一般 MySQL、Hadoop 的 master 是不一样的。它即不是写入流量的唯一入口,也不是所有数据的元信息的存放地点。所以,一般来说,ES 的 master 节点负载很轻,集群性能是可以近似认为随着 data 节点的扩展线性提升的。 但是,上面这句话并不是完全正确的。 ES 中有一件事情是只有 master 节点能管理的,这就是集群状态(cluster state)。 集群状态中包括以下信息: 这些信息在集群的任意节点上都存放着,你也可以通过 /_cluster/state 接口直接读取到其内容。注意这最后一项信息,之前我们已经讲过 ES 怎么通过简单地取余知道一条数据放在哪个分片里,加上现在集群状态里又记载了分片在哪个节点上,那么,整个集群里,任意节点都可以知道一条数据在哪个节点上存储了。所以,数据读写才可以发送给集群里任意节点。 至于修改,则只能由 master 节点完成!显然,集群状态里大部分内容是极少变动的,唯独有一样除外——索引的映射。因为 ES 的 schema-less 特性,我们可以任意写入 JSON 数据,所以索引中随时可能增加新的字段。这个时候,负责容纳这条数据的主分片所在的节点,会暂停写入操作,将字段的映射结果传递给 master 节点;master 节点合并这段修改到集群状态里,发送新版本的集群状态到集群的所有节点上。然后写入操作才会继续。一般来说,这个操作是在一二十毫秒内就可以完成,影响也不大。 但是也有一些情况会是例外。 在较大规模的 Elastic Stack 应用场景中,这是比较常见的一个情况。因为 Elastic Stack 建议采用日期时间作为索引的划分方式,所以定时(一般是每天),会统一产生一批新的索引。而前面已经讲过,ES 的集群状态每次更新都是阻塞式的发布到全部节点上以后,节点才能继续后续处理。 这就意味着,如果在集群负载较高的时候,批量新建新索引,可能会有一个显著的阻塞时间,无法写入任何数据。要等到全部节点同步完成集群状态以后,数据写入才能恢复。 不巧的是,中国使用的是北京时间,UTC +0800。也就是说,默认的 Elastic Stack 新建索引时间是在早上 8 点。这个时间点一般日志写入量已经上涨到一定水平了(当然,晚上 0 点的量其实也不低)。 对此,可以通过定时任务,每天在最低谷的早上三四点,提前通过 POST mapping 的方式,创建好之后几天的索引。就可以避免这个问题了。 如果你的日志是比较严重的非结构化数据,这个问题在 2.0 版本后会变得更加严重。 Elasticsearch 从 2.0 版本开始,对 mapping 更新做了重构。为了防止字段类型冲突和减少 master 定期下发全量 cluster state 导致的大流量压力,新的实现和旧实现的区别在: 也就是说,一旦你日志中字段数量较多,在新创建索引的一段时间内,可能长达几十分钟一直被反复锁死! 这是另一种常见的滥用。在使用 Elastic Stack 处理访问日志时,为了查询更方便,可能会采用 logstash-filter-kv 插件,将访问日志中的每个 URL 参数,都切分成单独的字段。比如一个 "/index.do?uid=1234567890&action=payload" 的 URL 会被转换成如下 JSON: 但是,因为集群状态是存在所有节点的内存里的,一旦 URL 参数过多,ES 节点的内存就被大量用于存储字段映射内容。这是一个极大的浪费。如果碰上 URL 参数的键内容本身一直在变动,直接撑爆 ES 内存都是有可能的! 以上是真实发生的事件,开发人员莫名的选择将一个 UUID 结果作为 key 放在 URL 参数里。直接导致 ES 集群 master 节点全部 OOM。 如果你在 ES 日志中一直看到有新的 updating mapping [logstash-2015.06.01] 字样出现的话,请郑重考虑一下自己是不是用的上如此细分的字段列表吧。 好,三秒钟过去,如果你确定一定以及肯定还要这么做,下面是一个变通的解决办法。 用 nested object 来存放 URL 参数的方法稍微复杂,但还可以接受。单从 JSON 数据层面看,新方式的数据结构如下: 没错,看起来就是一个数组。但是 JSON 数组在 ES 里是有两种处理方式的。 如果直接写入数组,ES 在实际索引过程中,会把所有内容都平铺开,变成 Arrays of Inner Objects 。整条数据实际类似这样的结构: 这种方式最大的问题是,当你采用 urlargs.key:"uid" AND urlargs.value:"0987654321" 语句意图搜索一个 uid=0987654321 的请求时,实际是整个 URL 参数中任意一处 value 为 0987654321 的,都会命中。 要想达到正确搜索的目的,需要在写入数据之前,指定 urlargs 字段的映射类型为 nested object。命令如下: 这样,数据实际是类似这样的结构: 当然,nested object 节省字段映射的优势对应的是它在使用的复杂。Query 和 Aggs 都必须使用专门的 nested query 和 nested aggs 才能正确读取到它。 nested query 语法如下: nested aggs 语法如下: ES 内针对不同阶段,设计有不同的缓存。以此提升数据检索时的响应性能。主要包括节点层面的 filter cache 和分片层面的 request cache。下面分别讲述。 ES 的 query DSL 在 2.0 版本之前分为 query 和 filter 两种,很多检索语法,是同时存在 query 和 filter 里的。比如最常用的 term、prefix、range 等。怎么选择是使用 query 还是 filter 成为很多用户头疼的难题。于是从 2.0 版本开始,ES 干脆合并了 filter 统一归为 query。但是具体的检索语法本身,依然有 query 和 filter 上下文的区别。ES 依靠这个上下文判断,来自动决定是否启用 filter cache。 query 跟 filter 上下文的区别,简单来说: 所以,选择也就出来了: 不过我们要怎么写,才能让 ES 正确判断呢?看下面这个请求: 在这个请求中, 需要注意的是,filter cache 是节点层面的缓存设置,每个节点上所有数据在响应请求时,是共用一个缓存空间的。当空间用满,按照 LRU 策略淘汰掉最冷的数据。 可以用 indices.cache.filter.size 配置来设置这个缓存空间的大小,默认是 JVM 堆的 10%,也可以设置一个绝对值。注意这是一个静态值,必须在 elasticsearch.yml 中提前配置。 ES 还有另一个分片层面的缓存,叫 shard request cache。5.0 之前的版本中,request cache 的用途并不大,因为 query cache 要起作用,还有几个先决条件: 以 Elastic Stack 场景来说,Kibana 里几乎所有的请求,都是有 @timestamp 作为过滤条件的,而且大多数是以 最近 N 小时/分钟 这样的选项,也就是说,页面每次刷新,发出的请求 JSON 里的时间过滤部分都是在变动的。query cache 在处理 Kibana 发出的请求时,完全无用。 而 5.0 版本的一大特性,叫 instant aggregation。解决了这个先决条件的一大阻碍。 在之前的版本,Elasticsearch 接收到请求之后,直接把请求原样转发给各分片,由各分片所在的节点自行完成请求的解析,进行实际的搜索操作。所以缓存的键是原始 JSON 串。 而 5.0 的重构后,接收到请求的节点先把请求的解析做完,发送到各节点的是统一拆分修改好的请求,这样就不再担心 JSON 串多个空格啥的了。 其次,上面说的『拆分修改』是怎么回事呢? 比如,我们在 Kibana 里搜索一个最近 7 天( @timestamp:["now-7d" TO "now"] )的数据,ES 就可以根据按天索引的判断,知道从 6 天前到昨天这 5 个索引是肯定全覆盖的。那么这个横跨 7 天的 date range query 就变成了 5 个 match_all query 加 2 个短时间的 date_range query。 现在你的仪表盘过 5 分钟自动刷新一次,再提交上来一次最近 7 天的请求,中间这 5 个 match_all 就完全一样了,直接从 request cache 返回即可,需要重新请求的,只有两头真正在变动的 date_range 了。 注1: match_all 不用遍历倒排索引,比直接查询 @timestamp:* 要快很多。 注2:判断覆盖修改为 match_all 并不是真的按照索引名称,而是 ES 从 2.x 开始提供的 field_stats 接口可以直接获取到 @timestamp 在本索引内的 max/min 值。当然从概念上如此理解也是可以接受的。 响应结果如下: 和 filter cache 一样,request cache 的大小也是以节点级别控制的,配置项名为 indices.requests.cache.size ,其默认值为 1% 。 字段数据(fielddata),在 Lucene 中又叫 uninverted index。我们都知道,搜索引擎会使用倒排索引(inverted index)来映射单词到文档的 ID 号。而同时,为了提供对文档内容的聚合,Lucene 还可以在运行时将每个字段的单词以字典序排成另一个 uninverted index,可以大大加速计算性能。 作为一个加速性能的方式,fielddata 当然是被全部加载在内存的时候最为有效。这也是 ES 默认的运行设置。但是,内存是有限的,所以 ES 同时也需要提供对 fielddata 内存的限额方式: Elasticsearch 在 total,fielddata,request 三个层面上都设计有 circuit breaker 以保护进程不至于发生 OOM 事件。在 fielddata 层面,其设置为: 但是相比较集群庞大的数据量,内存本身是远远不够的。为了解决这个问题,ES 引入了另一个特性,可以对精确索引的字段,指定 fielddata 的存储方式。这个配置项叫: doc_values 。 所谓 doc_values ,其实就是在 ES 将数据写入索引的时候,提前生成好 fielddata 内容,并记录到磁盘上。因为 fielddata 数据是顺序读写的,所以即使在磁盘上,通过文件系统层的缓存,也可以获得相当不错的性能。 注意:因为 doc_values 是在数据写入时即生成内容,所以,它只能应用在精准索引的字段上,因为索引进程没法知道后续会有什么分词器生成的结果。 由于在 Elastic Stack 场景中, doc_values 的使用极其频繁,到 Elasticsearch 5.0 以后,这两者的区别被彻底强化成两个不同字段类型: text 和 keyword 。 等同于过去的: 而 等同于过去的: 也就是说,以后的用户,已经不太需要在意 fielddata 的问题了。不过依然有少数情况,你会需要对分词字段做聚合统计的话,你可以在自己接受范围内,开启这个特性: 你可以看到在上面加了一段 fielddata_frequency_filter 配置,这个配置是 segment 级别的。上面示例的意思是:只有这个 segment 里的文档数量超过 500 个,而且含有该字段的文档数量占该 segment 里的文档数量比例超过 10% 时,才加载这个 segment 的 fielddata。 下面是一个可能有用的对分词字段做聚合的示例: 这个示例可以对经过了 logstash-filter-punct 插件处理的数据,获取每种 punct 类型日志的关键词和对应的代表性日志原文。其效果类似 Splunk 的事件模式功能: [图片上传失败...(image-b0b69f-1511752650964)] 如果经过之前章节的一系列优化之后,数据确实超过了集群能承载的能力,除了拆分集群以外,最后就只剩下一个办法了:清除废旧索引。 为了更加方便的做清除数据,合并 segment,备份恢复等管理任务,Elasticsearch 在提供相关 API 的同时,另外准备了一个命令行工具,叫 curator 。curator 是 Python 程序,可以直接通过 pypi 库安装: 注意,是 elasticsearch-curator 不是 curator。PyPi 原先就有另一个项目叫这个名字 和 Elastic Stack 里其他组件一样,curator 也是被 Elastic.co 收购的原开源社区周边。收编之后同样进行了一次重构,命令行参数从单字母风格改成了长单词风格。新版本的 curator 命令可用参数如下: Options 包括: --host TEXT Elasticsearch host. --url_prefix TEXT Elasticsearch http url prefix. --port INTEGER Elasticsearch port. --use_ssl Connect to Elasticsearch through SSL. --http_auth TEXT Use Basic Authentication ex: user:pass --timeout INTEGER Connection timeout in seconds. --master-only Only operate on elected master node. --dry-run Do not perform any changes. --debug Debug mode --loglevel TEXT Log level --logfile TEXT log file --logformat TEXT Log output format [default|logstash]. --version Show the version and exit. --help Show this message and exit. Commands 包括: alias Index Aliasing allocation Index Allocation bloom Disable bloom filter cache close Close indices delete Delete indices or snapshots open Open indices optimize Optimize Indices replicas Replica Count Per-shard show Show indices or snapshots snapshot Take snapshots of indices (Backup) 针对具体的 Command,还可以继续使用 --help 查看该子命令的帮助。比如查看 close 子命令的帮助,输入 curator close --help ,结果如下: 在使用 1.4.0 以上版本的 Elasticsearch 前提下,curator 曾经主要的一个子命令 bloom 已经不再需要使用。所以,目前最常用的三个子命令,分别是 close , delete 和 optimize ,示例如下: 这一顿任务,结果是: logstash-mweibo-nginx-yyyy.mm.dd 索引保存最近 5 天, logstash-mweibo-client-yyyy.mm.dd 保存最近 10 天, logstash-mweibo-yyyy.mm.dd 索引保存最近 30 天;且所有七天前的 logstash-* 索引都暂时关闭不用;最后对所有非当日日志做 segment 合并优化。 profiler 是 Elasticsearch 5.0 的一个新接口。通过这个功能,可以看到一个搜索聚合请求,是如何拆分成底层的 Lucene 请求,并且显示每部分的耗时情况。 启用 profiler 的方式很简单,直接在请求里加一行即可: 可以看到其中对 query 和 aggs 部分的返回是不太一样的。 query 部分包括 collectors、rewrite 和 query 部分。对复杂 query,profiler 会拆分 query 成多个基础的 TermQuery,然后每个 TermQuery 再显示各自的分阶段耗时如下: 我们可以很明显的看到聚合统计在初始化阶段、收集阶段、构建阶段、汇总阶段分别花了多少时间,遍历了多少数据。 注意其中 reduce 阶段还没实现完毕,所有都是 0。因为目前 profiler 只能在 shard 级别上做统计。 collect 阶段的耗时,有助于我们调整对应 aggs 的 collect_mode 参数选择。目前 Elasticsearch 支持 breadth_first 和 depth_first 两种方式。 initialise 阶段的耗时,有助于我们调整对应 aggs 的 execution_hint 参数选择。目前 Elasticsearch 支持 map 、 global_ordinals_low_cardinality 、 global_ordinals 和 global_ordinals_hash 四种选择。在计算离散度比较大的字段统计值时,适当调整该参数,有益于节省内存和提高计算速度。 对高离散度字段值统计性能很关注的读者,可以关注 https://github.com/elastic/elasticsearch/pull/21626 这条记录的进展。 (本文完) 文本整理自《ELKstack权威指南》

Lucene、Elasticsearch、Solr区别

Lucene: java写的单机搜索引擎Solr和Elasticsearch都是流行的搜索引擎,都是基于Java,但它们有一些区别。Solr是基于Lucene的搜索服务器,而Elasticsearch是一个分布式搜索和分析引擎。Solr更适合传统的企业搜索场景,而Elasticsearch更适合实时搜索和分析场景。Elasticsearch还具有更好的可扩展性和更好的文档处理能力。还有新的搜索引擎,基于c++开发的小唐代码搜索引擎,基于rust开发的github代码搜索引擎。

MCSE MCP MCDBA 是什么?

微软专家认证(Microsoft Certified Professional,简称MCP)   获得微软专家认证资格就意味着,微软承认您已具备较高专业技术水平,能够运用微软产品或技术为企业单位中的商务活动提供所需解决方案。 微软认证系统管理员(Microsoft Certified Systems Administrator,简称MCSA)   获得微软认证系统管理员资格就意味着,微软承认您已具备较高专业技术水准,能够实施、管理和检修当前基于微软Windows2000和Windows .NET服务器平台的网络与系统环境。 微软认证系统工程师(Microsoft Certified Systems Engineer,简称MCSE)   获得微软认证系统工程师资格就意味着,微软承认您已具备较高专业技术水平,能够分析商业需求,并使用微软2000系列平台和微软服务器软件来设计并实现商务解决方案的基础架构。微软认证系统工程师是这方面最为重要的认证资格。微软认证数据库系统管理员(Microsoft Certified Database Administrator ,简称MCDBA)   获得微软认证数据库系统管理员资格就意味着,微软承认您已具备较高专业技术水平,能够围绕微软SQL Server?数据库系统开展实施与管理工作。 微软认证可以说是拿高薪,做金领的机票。有了这个认证在美国都不愁找不到好工作。对于要出国留学的同学这个认证还可以当学分使用。别的我也不说了,详细的微软认证介绍在这里:http://www.microsoft.com/china/learning/至于哈尔滨哪里微软认证教的好,我认为还是哈尔滨工大银河不错。从9几年开始就一直是微软考试的授权考点。详细的你自己去他们的网站咨询一下吧。http://www.milkyway-edu.com.cn/电话0451-86417604 86214945

H3CSE认证都考哪些内容啊?谢谢!!

你可以去关注一下鸿鹄论坛,或者去看一下h3c官方网站,而且,这些都是有题库的,都是题库的题,好考

MCSE认证各科考试重点和常见题型

  70-210:   该科主要考核WIN2000 ROFESSIONAL 的安装和管理,一般来说在准备70-210的同时一定需要将70-215的知识一并复习,正因为它是我们ITExamPrep.com推荐参加考试的第一个科目,考生对考试环境需要一个熟悉的过程,所以并没有想象中的简单,这也是我们把70-210考试难度列为适中的原因。   可能微软将70-210的考试设定为客户端方面的问题,所以大家觉得比较刁钻。其准备方式和后面的70-215大同小异,在考试前的操作重点主要放在控制台里面项目的使用和排错(要将其选项熟悉,否则会不明不白的错掉考题)。   70-210是整个MCSE认证过程中的第一科,熟悉考试环境,培养考试心态都是在这一科完成的,而且对以后的士气很有用,加之考试内容与平时实践结合较多,必须一次性通过。   70-210考试中经常涉及的考点和题型:   硬件冲突:其中以网卡、显卡、I/O设备为最常出现。   打印机的设置和排错:网络打印机的安装设置、排除故障问题以及打印权限和打印优先级的问题。   文件夹的性质问题:加密和压缩的差异,以及复制和移动后的存取问题。   文件夹的存取问题:NTFS的权限问题。   安全策略的问题:安全策略设置。   离线文件夹的问题:离线文件夹的使用、设置和排错。   70-215:   该科主要考核WIN2000 SERVER的安装和管理,这科的内容在以后的日常工作中实践的机会最多,应该具备有十分纯熟的操作能力及日后工作管理上的应变能力,所以我们ITExamPrep.com建议时间充裕的学员可以把70-215 TRAINING KIT上的习题认真做一遍,也为后来的考试科目打下扎实的基础。   建议学员在准备70-215的考试时务必仔细学习教材,认真实践教材上的实验,你在这门课上多花点时间是绝对值得的,因为后面的考试都是以WIN2000 SERVER为基础展开的。如果这科你没掌握好,后面的学习会非常辛苦;相反这科研究透彻了,后面的学习则会得心应手。   70-215所考的范围十分的广同时书也是最厚的,基本上WIN2000 SERVER有的几乎都有考到,所以说简单也不简单,说难又没有70-210难。   70-215考试中经常涉及的考点和题型:   磁盘的管理和应用:在此要注意RAID的种类和分别以及RAID还原方式,还有动态磁盘和基本磁盘的差异性及CRASH如何还原修复,考试比例大概10%。   NTFS权限和共享权限的重叠问题:在此要注意两种权限NTFS是AND 取权限以及SHARE FLODER 是AND 取权限,和NTFS与SHARE FLODER 重叠时必须取限制。   RIS(远程安装服务)的应用:建议各位查阅一下RIS的部分(基本上RIS在70-210、70-215、70-216、70-217都多少会涉及)。   RIS的排错:在这里会考核RIS部署的基本要素,有AD、RIS SERVER、DHCP、DNS缺一不可,还有RIS对于网卡的需求(有无PXE的部署方式)。   此外70-215也会涉及一点70-217中AD(活动目录)和70-216网络部份的内容,不多也较简单。   MST和MSI的部署及差异性:在70-215的部份大概只有一到两题,主要是在70-217会涉及。   70-216:   该科主要考核运行和管理微软Windows2000网络基本构造,包括对Windows2000网络服务器的深入了解以及它的运作原理:DHCP, WINS, DNS IPSEC CA和RRAS等是贯穿整个考试的中心内容,同时也需要了解实际子网的运作方式,要看一些配置网络协议安全和认证服务器的资料。   由于你掌握了70-210和70-215的内容,所以基本上能够理解Windows 2000操作系统的细节,了解Windows 2000网络服务器功能的基本知识。由于70-216内容繁多,这就需要集中精力进行大量的重点学习和实际操作来熟练以达到70-216考试的要求。建议先将相关教材看熟,再来多看有关排错的部分,这对分析考试题目很有帮助。   70-216考试中经常涉及的考点和题型:   DNS:70-216的考试中DNS、DHCP、RRAS是考得最多的,其常出现的题型大都是混合DNS、RRAS、DHCP,再加上长长的叙述和多选题。   DHCP:DHCP在此考了将近1/3是有着很重的比例,建议熟读。常考的有DNS、WINS、DEFAULT GETWAY的分配,以及DHCP RELAY AGENT(要判断其使用DHCP RELAY AGENT时机和位置)。   WINS:主要考备份和还原,以及一些管理上的小问题和WINS PROXY的题目。   RRAS:通常与DNS、DHCP、OSPF合在一起考,答题需仔细。   其它题型:例如局域网络IP的规划,子网掩码的算法,区网IP分割等和TCP/IP有关的计算和规划,大概3~4题左右。   70-217:   该科主要考核AD(活动目录)的使用和管理,AD是自WINDOWS NT4.0 以后微软管理上一个很大的突破,具备良好的AD管理基础也是一位真正MCSE所必须要掌握的技能之一。此科目和70-219差别为70-217为AD的安装和管理以及问题排除,而70-219为AD的建置计画(也就是规划公司企业的AD结构),所以有心将70-219一起准备的朋友,70-217的基础打好的话,考70-219还是很简单的。   70-217考试中经常涉及的考点和题型:   DNS:设置A活动目录一定涉及DNS,所以DNS在70-217的考试中也有举足轻重的地位,在此要注意AD和DNS结合的细节(包BIND的相关知识)以及DNS的安装设置。   RIS:其重要性不再赘述;   AD的备份和还原:注意授权还原和非授权还原的差异及步骤;   AD的数据库压缩:   MSI和MST的差异:注意MSI和MST的差别以及部署差异以及相关问题排除。   权限的设定和继承关系:SITE-->DOMAIN-->OU-->USER。   帐号群组建立原则:A-->G-->G-->U->DLG<--P。   70-219:   该科主要考核AD(活动目录)的设计,70-219基本上来说是一个综合科目,再加上前面70-217的基础踏实,考70-219就比较简单了,219之所以被列为“设计”,自有它的道理,给你一个案例比如一个有多个分部的公司环境,要求你做某些事情,技术要求不算难,应该讲219是一个关于AD设计与规划的大体轮廓,主要还是要理解问题给出的环境以及需要做到哪些要求。   70-219考试中经常涉及的考点和题型:   主要考核DNS ZONE与AD域的规划和设计。   70-228:   该科主要考核SQL SERVER 2000的安装、管理、及问题排除,因为和以前的考试没有太多的联系,等于重新开一科,所以还是多下点功夫才能过关。但是终究无非开帐号、建数据库、修复与备份和还原数据库,配合教材找出重点,并多多上手实际操作,也可以高分通过。   70-228考试中经常涉及的考点和题型:   T-SQL的程序设计:考的比较多的是有关SQL SERVER的管理应用语法,开帐号、建数据库等。   SQL的安装和升级:   数据库的建立:T-SQL的建立语法和ENTERPRISE MANAGER的建立方式。   监控程序的分析和解决效能瓶颈:要会分析数据和解决题目所给出的问题。   DTS的使用:   权限的问题:大致和70-210或70-215的权限出法差不多,但要熟悉每种角色身分的差异。   使用者自订函数和使用者自订预存程序的差别:   70-229:   该科主要考核SQL SERVER 2000数据库的配置和管理,考了很多T-SQL的程序设计,要求熟悉,否则容易失手,感觉70-229比70-228难得多,学员学习时要多多注意。   在真正的工作中为SQL Server做开发不是一件容易的事,要让SQL Server 运行得尽可能高效、快速不算容易,SQL Server开发人员除了要掌握好现有的技术、利用好现有的资源以外,还应该不断观察、了解SQL Server,掌握它的运行状态,在必要的时候找出影响运行效率的瓶颈所在。   70-229考试中经常涉及的考点和题型:   T-SQL的程序设计:考T-SQL语法的试题在70-229的考试中占据了相当多的题量,而且出题的方式有除错、修改、增加、判断使用语法是否正确等的很多种。   对于相关数据库需求的考题:这种类型的考题会有一段叙述,要注意其文字叙述内容,加以推敲答案就会浮现出来。

Elasticsearch7.8.0 配置x-pack基础安全

X-Pack是Elastic Stack扩展功能,提供安全性,警报,监视,报告,机器学习和许多其他功能。 ES7.0+之后,默认情况下,当安装Elasticsearch时,会安装X-Pack,无需单独再安装。 自6.8以及7.1+版本之后,基础级安全永久免费。 默认情况下,拥有安全免费许可证时,Elasticsearch安全功能被禁用。 要启用安全功能,需要设置xpack.security.enabled。 在每个节点的elasticsearch.yml配置文件中,新增: 使用范围:配置传输层安全性适用于具有多个节点的集群以及需要外网通信访问的单节点ES。 使用环回地址127.0.0.1的单节点ES可以不用配置。 Elasticsearch节点可能存储是机密的数据,而无处不在的网络攻击对这些数据垂涎欲滴。 网络攻击包括对数据的嗅探,对数据的操纵,以及试图获得对服务器的访问权限,进而访问存储数据的文件。 保护节点的安全有助于降低来自网络的攻击的风险 。 1、证书实现加密通信的原理 TLS需要X.509证书(X.509 证书是一个数字证书,它使用 X.509 公有密钥基础设施标准将公有密钥与证书中包含的身份相关联。X.509 证书由一家名为证书颁发机构 (CA) 的可信实体颁发。CA 持有一个或多个名为 CA 证书的特殊证书,它使用这种证书来颁发 X.509 证书。只有证书颁发机构才有权访问 CA 证书)才能对与之通信的应用程序执行加密和身份验证。 为了使节点之间的通信真正安全, 必须对证书进行验证 。 在Elasticsearch集群中验证证书真实性的推荐方法是信任签署证书的证书颁发机构(CA)。 这样,只需要使用由同一CA签名的证书,即可自动允许该节点加入集群。 2、借助elasticsearch-certutil命令生成证书 启用安全功能后,必须使用TLS来确保节点之间的通信已加密。 在elasticsearch.yml中心新增配置如下: 借助:elasticsearch-setup-passwords 设置集群密码。 核心: auto - 随机生成密码。 interactive - 自定义不同用户的密码。 注意:必须配置好xpack之后,才能设置密码。否则会报错。 最简单的方法, 假定是初始部署集群阶段。 X-Pack安全配置的核心三步骤: 这些对于安全来说只是皮毛,更多的角色、权限、Space需要借助Kibana实现。 5.1 pom文件 5.2修改配置文件

elasticsearch5.2.2怎么用java api创建索引

一、ElasticSearch是什么?ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的搜索引擎。能够达到实时搜索,稳定,可靠,快速,安装使用方便,零配置和完全。我们先说说ES的基本概念。1、索引(Index)ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。2、类型(Type)类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。3、文档(Document)文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。4、映射(Mapping)ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。5、集群(Cluster)ES集群是一个或多个节点的集合,它们共同存储了整个数据集,并提供了联合索引以及可跨所有节点的搜索能力。多节点组成的集群拥有冗余能力,它可以在一个或几个节点出现故障时保证服务的整体可用性。集群靠其独有的名称进行标识,默认名称为“elasticsearch”。节点靠其集群名称来决定加入哪个ES集群,一个节点只能属一个集群。如果不考虑冗余能力等特性,仅有一个节点的ES集群一样可以实现所有的存储及搜索功能。6、节点(Node)运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。7、分片(Shard)和副本(Replica)ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。ES可自动在节点间按需要移动shard,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。OK,上面把ES相关的基本概念及原理大致说明了下,那么ES到底是怎么实现全文检索的呢?Elasticsearch实现全文检索,首先要确定分词器,ES默认有很多分词器,可参考官方文档。了解分词器主要是怎么实现的。一般中文分词器使用第三方的ik分词器、mmsegf分词器和paoding分词器,最初可能构建于lucene,后来移植于ES。目前我们在最新版的ES中,使用的是IK分词。安装ik分词器到elasticsearch很简单,它有个插件目录analysis-ik,和一个配置目录ik, 分别拷贝到plugins和conf目录就可以了。当你有大量的文本数据时,ES均会将其进行分词并将这些词语保存在索引中,当输入关键词进行查询时,索引就会起到作用,查找对应的相同的查询词,从而实现全文检索。当然这个过程是很吃内存的哦。

怎么将更改elasticsearch服务端端口

elasticsearch的config文件夹里面有两个配置文 件:elasticsearch.yml和logging.yml,第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来记录日 志的,所以logging.yml里的设置按普通log4j配置文件来设置就行了。下面主要讲解下elasticsearch.yml这个文件中可配置的 东西。cluster.name: elasticsearch配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。node.name: "Franz Kafka"节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。node.master: true指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。

elasticsearch JPA执行save方法后,发现elasticsearch有文件生成,但数据库中没数据

由于需要提升项目的搜索质量,最近研究了一下Elasticsearch,一款非常优秀的分布式搜索程序。最开始的一些笔记放到github,这里只是归纳总结一下。首先,为什么要使用Elasticsearch?最开始的时候,我们的项目仅仅使用MySQL进行简单的搜索,然后一个不能索引的like语句,直接拉低MySQL的性能。后来,我们曾考虑过sphinx,并且sphinx也在之前的项目中成功实施过,但想想现在的数据量级,多台MySQL,以及搜索服务本身HA,还有后续扩容的问题,我们觉得sphinx并不是一个最优的选择。于是自然将目光放到了Elasticsearch上面。根据官网自己的介绍,Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard的方式保证数据安全,并且提供自动resharding的功能,加之github等大型的站点也采用 Elasticsearch作为其搜索服务,我们决定在项目中使用Elasticsearch。对于Elasticsearch,如果要在项目中使用,需要解决如下问题:索引,对于需要搜索的数据,如何建立合适的索引,还需要根据特定的语言使用不同的analyzer等。搜索,Elasticsearch提供了非常强大的搜索功能,如何写出高效的搜索语句?数据源,我们所有的数据是存放到MySQL的,MySQL是唯一数据源,如何将MySQL的数据导入到Elasticsearch?对于1和2,因为我们的数据都是从MySQL生成,index的field是固定的,主要做的工作就是根据业务场景设计好对应的mapping以及search语句就可以了,当然实际不可能这么简单,需要我们不断的调优。而对于3,则是需要一个工具将MySQL的数据导入Elasticsearch,因为我们对搜索实时性要求很高,所以需要将MySQL的增量数据实时导入,笔者唯一能想到的就是通过row based binlog来完成。而近段时间的工作,也就是实现一个MySQL增量同步到Elasticsearch的服务。LuceneElasticsearch底层是基于Lucene的,Lucene是一款优秀的搜索lib,当然,笔者以前仍然没有接触使用过。:-)Lucene关键概念:Document:用来索引和搜索的主要数据源,包含一个或者多个Field,而这些Field则包含我们跟Lucene交互的数据。Field:Document的一个组成部分,有两个部分组成,name和value。Term:不可分割的单词,搜索最小单元。Token:一个Term呈现方式,包含这个Term的内容,在文档中的起始位置,以及类型。Lucene使用Inverted index来存储term在document中位置的映射关系。譬如如下文档:Elasticsearch Server 1.0 (document 1)Mastring Elasticsearch (document 2)Apache Solr 4 Cookbook (document 3)使用inverted index存储,一个简单地映射关系:TermCountDocuemnt1.0 14 1Apache 1Cookbook 1Elasticsearch 2 .Mastering 1Server 1Solr 1对于上面例子,我们首先通过分词算法将一个文档切分成一个一个的token,再得到该token与document的映射关系,并记录token出现的总次数。这样就得到了一个简单的inverted index。Elasticsearch关键概念要使用Elasticsearch,笔者认为,只需要理解几个基本概念就可以了。在数据层面,主要有:Index:Elasticsearch用来存储数据的逻辑区域,它类似于关系型数据库中的db概念。一个index可以在一个或者多个shard上面,同时一个shard也可能会有多个replicas。Document:Elasticsearch里面存储的实体数据,类似于关系数据中一个table里面的一行数据。document由多个field组成,不同的document里面同名的field一定具有相同的类型。document里面field可以重复出现,也就是一个field会有多个值,即multivalued。Document type:为了查询需要,一个index可能会有多种document,也就是document type,但需要注意,不同document里面同名的field一定要是相同类型的。Mapping:存储field的相关映射信息,不同document type会有不同的mapping。对于熟悉MySQL的童鞋,我们只需要大概认为Index就是一个db,document就是一行数据,field就是table的column,mapping就是table的定义,而document type就是一个table就可以了。Document type这个概念其实最开始也把笔者给弄糊涂了,其实它就是为了更好的查询,举个简单的例子,一个index,可能一部分数据我们想使用一种查询方式,而另一部分数据我们想使用另一种查询方式,于是就有了两种type了。不过这种情况应该在我们的项目中不会出现,所以通常一个index下面仅会有一个 type。在服务层面,主要有:Node: 一个server实例。Cluster:多个node组成cluster。Shard:数据分片,一个index可能会存在于多个shards,不同shards可能在不同nodes。Replica:shard的备份,有一个primary shard,其余的叫做replica shards。Elasticsearch之所以能动态resharding,主要在于它最开始就预先分配了多个shards(貌似是1024),然后以shard为单位进行数据迁移。这个做法其实在分布式领域非常的普遍,codis就是使用了1024个slot来进行数据迁移。因为任意一个index都可配置多个replica,通过冗余备份的方式保证了数据的安全性,同时replica也能分担读压力,类似于MySQL中的slave。Restful APIElasticsearch提供了Restful API,使用json格式,这使得它非常利于与外部交互,虽然Elasticsearch的客户端很多,但笔者仍然很容易的就写出了一个简易客户端用于项目中,再次印证了Elasticsearch的使用真心很容易。Restful的接口很简单,一个url表示一个特定的资源,譬如/blog/article/1,就表示一个index为blog,type为aritcle,id为1的document。而我们使用http标准method来操作这些资源,POST新增,PUT更新,GET获取,DELETE删除,HEAD判断是否存在。这里,友情推荐httpie,一个非常强大的http工具,个人感觉比curl还用,几乎是命令行调试Elasticsearch的绝配。一些使用httpie的例子:# createhttp POST :9200/blog/article/1 title="hello elasticsearch" tags:="["elasticsearch"]"# gethttp GET :9200/blog/article/1# updatehttp PUT :9200/blog/article/1 title="hello elasticsearch" tags:="["elasticsearch", "hello"]"# deletehttp DELETE :9200/blog/article/1# existshttp HEAD :9200/blog/article/1索引和搜索虽然Elasticsearch能自动判断field类型并建立合适的索引,但笔者仍然推荐自己设置相关索引规则,这样才能更好为后续的搜索服务。我们通过定制mapping的方式来设置不同field的索引规则。而对于搜索,Elasticsearch提供了太多的搜索选项,就不一一概述了。索引和搜索是Elasticsearch非常重要的两个方面,直接关系到产品的搜索体验,但笔者现阶段也仅仅是大概了解了一点,后续在详细介绍。同步MySQL数据Elasticsearch是很强大,但要建立在有足量数据情况下面。我们的数据都在MySQL上面,所以如何将MySQL的数据导入Elasticsearch就是笔者最近研究的东西了。虽然现在有一些实现,譬如elasticsearch-river-jdbc,或者elasticsearch-river-mysql,但笔者并不打算使用。elasticsearch-river-jdbc的功能是很强大,但并没有很好的支持增量数据更新的问题,它需要对应的表只增不减,而这个几乎在项目中是不可能办到的。elasticsearch-river-mysql倒是做的很不错,采用了python-mysql-replication来通过binlog获取变更的数据,进行增量更新,但它貌似处理MySQL dump数据导入的问题,不过这个笔者真的好好确认一下?话说,python-mysql-replication笔者还提交过pull解决了minimal row image的问题,所以对elasticsearch-river-mysql这个项目很有好感。只是笔者决定自己写一个出来。为什么笔者决定自己写一个,不是因为笔者喜欢造轮子,主要原因在于对于这种MySQL syncer服务(增量获取MySQL数据更新到相关系统),我们不光可以用到Elasticsearch上面,而且还能用到其他服务,譬如cache上面。所以笔者其实想实现的是一个通用MySQL syncer组件,只是现在主要关注Elasticsearch罢了。项目代码在这里go-mysql-elasticsearch,现已完成第一阶段开发,内部对接测试中。go-mysql-elasticsearch的原理很简单,首先使用mysqldump获取当前MySQL的数据,然后在通过此时binlog的name和position获取增量数据。一些限制:binlog一定要变成row-based format格式,其实我们并不需要担心这种格式的binlog占用太多的硬盘空间,MySQL 5.6之后GTID模式都推荐使用row-based format了,而且通常我们都会把控SQL语句质量,不允许一次性更改过多行数据的。需要同步的table最好是innodb引擎,这样mysqldump的时候才不会阻碍写操作。需要同步的table一定要有主键,好吧,如果一个table没有主键,笔者真心会怀疑设计这个table的同学编程水平了。多列主键也是不推荐的,笔者现阶段不打算支持。一定别动态更改需要同步的table结构,Elasticsearch只能支持动态增加field,并不支持动态删除和更改field。通常来说,如果涉及到alter table,很多时候已经证明前期设计的不合理以及对于未来扩展的预估不足了。更详细的说明,等到笔者完成了go-mysql-elasticsearch的开发,并通过生产环境中测试了,再进行补充。总结最近一周,笔者花了不少时间在Elasticsearch上面,现在算是基本入门了。其实笔者觉得,对于一门不懂的技术,找一份靠谱的资料(官方文档或者入门书籍),蛋疼的对着资料敲一遍代码,不懂的再问google,最后在将其用到实际项目,这门技术就算是初步掌握了,当然精通还得在下点功夫。现在笔者只是觉得Elasticsearch很美好,上线之后铁定会有坑的,那时候只能慢慢填了。话说,笔者是不是要学习下java了,省的到时候看不懂代码就惨了。:-)

elasticsearch 把很多类型都放在一个索引下面 会不会导致查询慢

主要看数据量ES索引优化篇主要从两个方面解决问题,一是索引数据过程;二是检索过程。(本文主要介绍)索引数据过程我在上面几篇文章中有提到怎么创建索引和导入数据,但是大家可能会遇到索引数据比较慢的过程。其实明白索引的原理就可以有针对性的进行优化。ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡。所以从上我可以通过索引的settings进行第一优化:“index.translog.flush_threshold_ops”: “100000″“index.refresh_interval”: “-1″,这两个参数第一是到tranlog数据达到多少条进行平衡,默认为5000,而这个过程相对而言是比较浪费时间和资源的。所以我们可以将这个值调大一些还是设为-1关闭,进而手动进行tranlog平衡。第二参数是刷新频率,默认为120s是指索引在生命周期内定时刷新,一但有数据进来能refresh像lucene里面commit,我们知道当数据addDoucment会,还不能检索到要commit之后才能行数据的检索所以可以将其关闭,在最初索引完后手动refresh一之,然后将索引setting里面的index.refresh_interval参数按需求进行修改,从而可以提高索引过程效率。另外的知道ES索引过程中如果有副本存在,数据也会马上同步到副本中去。我个人建议在索引过程中将副本数设为0,待索引完成后将副本数按需量改回来,这样也可以提高索引效率。“number_of_replicas”: 0上面聊了一次索引过程的优化之后,我们再来聊一下检索速度比较慢的问题,其实检索速度快度与索引质量有很大的关系。而索引质量的好坏与很多因素有关。一、分片数分片数,与检索速度非常相关的的指标,如果分片数过少或过多都会导致检索比较慢。分片数过多会导致检索时打开比较多的文件别外也会导致多台服务器之间通讯。而分片数过少为导至单个分片索引过大,所以检索速度慢。在确定分片数之前需要进行单服务单索引单分片的测试。比如我之前在IBM-3650的机器上,创建一个索引,该索引只有一个分片,分别在不同数据量的情况下进行检索速度测试。最后测出单个分片的内容为20G。所以索引分片数=数据总量/单分片数目前,我们数据量为4亿多条,索引大小为近1.5T左右。因为是文档数据所以单数据都中8K以前。现在检索速度保证在100ms 以下。特别情况在500ms以下,做200,400,800,1000,1000+用户长时间并发测试时最坏在750ms以下.二、副本数副本数与索引的稳定性有比较大的关系,怎么说,如果ES在非正常挂了,经常会导致分片丢失,为了保证这些数据的完整性,可以通过副本来解决这个问题。建议在建完索引后在执行Optimize后,马上将副本数调整过来。大家经常有一个误去副本越多,检索越快,这是不对的,副本对于检索速度其它是减无增的我曾做过实现,随副本数的增加检索速度会有微量的下降,所以大家在设置副本数时,需要找一个平衡值。另外设置副本后,大家有可能会出现两次相同检索,出现出现不同值的情况,这里可能是由于tranlog没有平衡、或是分片路由的问题,可以通过?preference=_primary 让检索在主片分上进行。三、分词其实分词对于索引的影响可大可小,看自己把握。大家越许认为词库的越多,分词效果越好,索引质量越好,其实不然。分词有很多算法,大部分基于词表进行分词。也就是说词表的大小决定索引大小。所以分词与索引膨涨率有直接链接。词表不应很多,而对文档相关特征性较强的即可。比如论文的数据进行建索引,分词的词表与论文的特征越相似,词表数量越小,在保证查全查准的情况下,索引的大小可以减少很多。索引大小减少了,那么检索速度也就提高了。四、索引段索引段即lucene中的segments概念,我们知道ES索引过程中会refresh和tranlog也就是说我们在索引过程中segments number不至一个。而segments number与检索是有直接联系的,segments number越多检索越慢,而将segments numbers 有可能的情况下保证为1这将可以提到将近一半的检索速度。$ curl -XPOST ‘http://localhost:9200/twitter/_optimize? max_num_segments =1′五、删除文档删除文档在Lucene中删除文档,数据不会马上进行硬盘上除去,而进在lucene索引中产生一个.del的文件,而在检索过程中这部分数据也会参与检索,lucene在检索过程会判断是否删除了,如果删除了在过滤掉。这样也会降低检索效率。所以可以执行清除删除文档。$ curl -XPOST ‘http://localhost:9200/twitter/_optimize? only_expunge_deletes =true

elasticsearch应该通过什么方式建立连接

由于需要提升项目的搜索质量,最近研究了一下Elasticsearch,一款非常优秀的分布式搜索程序。最开始的一些笔记放到github,这里只是归纳总结一下。首先,为什么要使用Elasticsearch?最开始的时候,我们的项目仅仅使用MySQL进行简单的搜索,然后一个不能索引的like语句,直接拉低MySQL的性能。后来,我们曾考虑过sphinx,并且sphinx也在之前的项目中成功实施过,但想想现在的数据量级,多台MySQL,以及搜索服务本身HA,还有后续扩容的问题,我们觉得sphinx并不是一个最优的选择。于是自然将目光放到了Elasticsearch上面。根据官网自己的介绍,Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard的方式保证数据安全,并且提供自动resharding的功能,加之github等大型的站点也采用 Elasticsearch作为其搜索服务,我们决定在项目中使用Elasticsearch。对于Elasticsearch,如果要在项目中使用,需要解决如下问题:索引,对于需要搜索的数据,如何建立合适的索引,还需要根据特定的语言使用不同的analyzer等。搜索,Elasticsearch提供了非常强大的搜索功能,如何写出高效的搜索语句?数据源,我们所有的数据是存放到MySQL的,MySQL是唯一数据源,如何将MySQL的数据导入到Elasticsearch?对于1和2,因为我们的数据都是从MySQL生成,index的field是固定的,主要做的工作就是根据业务场景设计好对应的mapping以及search语句就可以了,当然实际不可能这么简单,需要我们不断的调优。而对于3,则是需要一个工具将MySQL的数据导入Elasticsearch,因为我们对搜索实时性要求很高,所以需要将MySQL的增量数据实时导入,笔者唯一能想到的就是通过row based binlog来完成。而近段时间的工作,也就是实现一个MySQL增量同步到Elasticsearch的服务。LuceneElasticsearch底层是基于Lucene的,Lucene是一款优秀的搜索lib,当然,笔者以前仍然没有接触使用过。:-)Lucene关键概念:Document:用来索引和搜索的主要数据源,包含一个或者多个Field,而这些Field则包含我们跟Lucene交互的数据。Field:Document的一个组成部分,有两个部分组成,name和value。Term:不可分割的单词,搜索最小单元。Token:一个Term呈现方式,包含这个Term的内容,在文档中的起始位置,以及类型。Lucene使用Inverted index来存储term在document中位置的映射关系。譬如如下文档:Elasticsearch Server 1.0 (document 1)Mastring Elasticsearch (document 2)Apache Solr 4 Cookbook (document 3)使用inverted index存储,一个简单地映射关系:TermCountDocuemnt1.0 1 <1> 4 1 <3> Apache 1 <3> Cookbook 1 <3> Elasticsearch 2 <1>.<2> Mastering 1 <2> Server 1 <1> Solr 1 <3> 对于上面例子,我们首先通过分词算法将一个文档切分成一个一个的token,再得到该token与document的映射关系,并记录token出现的总次数。这样就得到了一个简单的inverted index。Elasticsearch关键概念要使用Elasticsearch,笔者认为,只需要理解几个基本概念就可以了。在数据层面,主要有:Index:Elasticsearch用来存储数据的逻辑区域,它类似于关系型数据库中的db概念。一个index可以在一个或者多个shard上面,同时一个shard也可能会有多个replicas。Document:Elasticsearch里面存储的实体数据,类似于关系数据中一个table里面的一行数据。document由多个field组成,不同的document里面同名的field一定具有相同的类型。document里面field可以重复出现,也就是一个field会有多个值,即multivalued。Document type:为了查询需要,一个index可能会有多种document,也就是document type,但需要注意,不同document里面同名的field一定要是相同类型的。Mapping:存储field的相关映射信息,不同document type会有不同的mapping。对于熟悉MySQL的童鞋,我们只需要大概认为Index就是一个db,document就是一行数据,field就是table的column,mapping就是table的定义,而document type就是一个table就可以了。Document type这个概念其实最开始也把笔者给弄糊涂了,其实它就是为了更好的查询,举个简单的例子,一个index,可能一部分数据我们想使用一种查询方式,而另一部分数据我们想使用另一种查询方式,于是就有了两种type了。不过这种情况应该在我们的项目中不会出现,所以通常一个index下面仅会有一个 type。在服务层面,主要有:Node: 一个server实例。Cluster:多个node组成cluster。Shard:数据分片,一个index可能会存在于多个shards,不同shards可能在不同nodes。Replica:shard的备份,有一个primary shard,其余的叫做replica shards。Elasticsearch之所以能动态resharding,主要在于它最开始就预先分配了多个shards(貌似是1024),然后以shard为单位进行数据迁移。这个做法其实在分布式领域非常的普遍,codis就是使用了1024个slot来进行数据迁移。因为任意一个index都可配置多个replica,通过冗余备份的方式保证了数据的安全性,同时replica也能分担读压力,类似于MySQL中的slave。Restful APIElasticsearch提供了Restful API,使用json格式,这使得它非常利于与外部交互,虽然Elasticsearch的客户端很多,但笔者仍然很容易的就写出了一个简易客户端用于项目中,再次印证了Elasticsearch的使用真心很容易。Restful的接口很简单,一个url表示一个特定的资源,譬如/blog/article/1,就表示一个index为blog,type为aritcle,id为1的document。而我们使用http标准method来操作这些资源,POST新增,PUT更新,GET获取,DELETE删除,HEAD判断是否存在。这里,友情推荐httpie,一个非常强大的http工具,个人感觉比curl还用,几乎是命令行调试Elasticsearch的绝配。一些使用httpie的例子:# createhttp POST :9200/blog/article/1 title="hello elasticsearch" tags:="["elasticsearch"]"# gethttp GET :9200/blog/article/1# updatehttp PUT :9200/blog/article/1 title="hello elasticsearch" tags:="["elasticsearch", "hello"]"# deletehttp DELETE :9200/blog/article/1# existshttp HEAD :9200/blog/article/1索引和搜索虽然Elasticsearch能自动判断field类型并建立合适的索引,但笔者仍然推荐自己设置相关索引规则,这样才能更好为后续的搜索服务。我们通过定制mapping的方式来设置不同field的索引规则。而对于搜索,Elasticsearch提供了太多的搜索选项,就不一一概述了。索引和搜索是Elasticsearch非常重要的两个方面,直接关系到产品的搜索体验,但笔者现阶段也仅仅是大概了解了一点,后续在详细介绍。同步MySQL数据Elasticsearch是很强大,但要建立在有足量数据情况下面。我们的数据都在MySQL上面,所以如何将MySQL的数据导入Elasticsearch就是笔者最近研究的东西了。虽然现在有一些实现,譬如elasticsearch-river-jdbc,或者elasticsearch-river-mysql,但笔者并不打算使用。elasticsearch-river-jdbc的功能是很强大,但并没有很好的支持增量数据更新的问题,它需要对应的表只增不减,而这个几乎在项目中是不可能办到的。elasticsearch-river-mysql倒是做的很不错,采用了python-mysql-replication来通过binlog获取变更的数据,进行增量更新,但它貌似处理MySQL dump数据导入的问题,不过这个笔者真的好好确认一下?话说,python-mysql-replication笔者还提交过pull解决了minimal row image的问题,所以对elasticsearch-river-mysql这个项目很有好感。只是笔者决定自己写一个出来。为什么笔者决定自己写一个,不是因为笔者喜欢造轮子,主要原因在于对于这种MySQL syncer服务(增量获取MySQL数据更新到相关系统),我们不光可以用到Elasticsearch上面,而且还能用到其他服务,譬如cache上面。所以笔者其实想实现的是一个通用MySQL syncer组件,只是现在主要关注Elasticsearch罢了。项目代码在这里go-mysql-elasticsearch,现已完成第一阶段开发,内部对接测试中。go-mysql-elasticsearch的原理很简单,首先使用mysqldump获取当前MySQL的数据,然后在通过此时binlog的name和position获取增量数据。一些限制:binlog一定要变成row-based format格式,其实我们并不需要担心这种格式的binlog占用太多的硬盘空间,MySQL 5.6之后GTID模式都推荐使用row-based format了,而且通常我们都会把控SQL语句质量,不允许一次性更改过多行数据的。需要同步的table最好是innodb引擎,这样mysqldump的时候才不会阻碍写操作。需要同步的table一定要有主键,好吧,如果一个table没有主键,笔者真心会怀疑设计这个table的同学编程水平了。多列主键也是不推荐的,笔者现阶段不打算支持。一定别动态更改需要同步的table结构,Elasticsearch只能支持动态增加field,并不支持动态删除和更改field。通常来说,如果涉及到alter table,很多时候已经证明前期设计的不合理以及对于未来扩展的预估不足了。更详细的说明,等到笔者完成了go-mysql-elasticsearch的开发,并通过生产环境中测试了,再进行补充。总结最近一周,笔者花了不少时间在Elasticsearch上面,现在算是基本入门了。其实笔者觉得,对于一门不懂的技术,找一份靠谱的资料(官方文档或者入门书籍),蛋疼的对着资料敲一遍代码,不懂的再问google,最后在将其用到实际项目,这门技术就算是初步掌握了,当然精通还得在下点功夫。现在笔者只是觉得Elasticsearch很美好,上线之后铁定会有坑的,那时候只能慢慢填了。话说,笔者是不是要学习下java了,省的到时候看不懂代码就惨了。:-)

kibana配置elasticsearchurl选项 怎么才能配置灵活

Kibana是一个为ElasticSearch提供的数据分析的Web接口。可使用它对日志进行高效的搜索、可视化、分析等各种操作。Kibana目前最新的版本5.0.2,回顾一下Kibana3和Kibana4的界面。

elasticsearch索引主要实现方式

Elasticsearch是什么?Elasticsearch是位于ElasticStack核心的分布式搜索和分析引擎。Logstash和Beats有助于收集、聚合和丰富您的数据并将其存储在Elasticsearch中。Kibana使您能够以交互方式探索、可视化和分享对数据的见解,并管理。Elasticsearch是一个分布式文档存储。Elasticsearch存储的是序列化为JSON文档的复杂数据结构,而不是以列行数据的形式存储信息。当集群中有多个Elasticsearch节点时,存储的文档分布在整个集群中,可以立即从任何节点访问。Elasticsearch是由ShayBanon发起的一个开源搜索服务器项目,2010年2月发布。迄今,该项目已发展成为搜索和数据分析解决方案领域的主要一员,广泛应用于声名卓著或鲜为人知的搜索应用程序。Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎。它可以在很短的时间内存储,搜索和分析大量的数据。它通常作为具有复杂搜索场景情况下的核心发动机。搜索引擎,不支持join表等操作。主要用于全文检索。不适合做数据库。如何选择合适的数据库解决方案?1、如果有强大的技术团队,关系型和非关系型数据库都可选择。一般来讲,非关系型数据库需要更多管理维护的时间。2、如果你要储存会话信息,用户配置信息,购物车数据,建议使用NoSQL数据库;不过90%的企业或个人,首选数据库都是MySQL数据库。3、(一)、Access(二)SQLServer(三)MySQL,Access是一种桌面数据库,只适合数据量少的应用,在处理少量数据和单机访问的数据库时是很好的,效率也很高。但是它的同时访问客户端不能多于4个。4、虽然把上面的架构全部组合在一起可以形成一个强大的高可用,高负载的数据库系统,但是架构选择合适才是最重要的。混合架构虽然能够解决所有的场景的问题,但是也会面临更多的挑战,你以为的完美架构,背后其实有着更多的坑。5、例如,如果你需要的是数据分析仓库,关系数据库可能不是一个适合的选择;如果你处理事务的应用要求严格的数据完整性和一致性,就不要考虑NoSQL了。不要重新发明轮子在过去的数十年,开源数据库技术迅速发展壮大。6、本文首先讨论了基于第三范式的数据库表的基本设计,着重论述了建立主键和索引的策略和方案,然后从数据库表的扩展设计和库表对象的放置等角度概述了数据库管理系统的优化方案。ElasticSearch倒排索引及其原理1、倒排索引采用ImmutableDesign,一旦生成,不可更改。Segment写入磁盘的过程相对耗时,所以借助文件系统缓存,Refresh时,先将Segment写入文件缓存中,以开放查询。2、之前我们已经了解过,Elasticsearch是一个基于Lucene实现的分布式全文检索引擎,其实Elasticsearch倒排索引就是Lucene的倒排索引。3、所谓的倒排索引,就是把你的数据内容先分词,每句话分成一个一个的关键词,然后记录好每一个关键词对应出现在了哪些id标识的数据。4、可以将对es的操作记录下来,来确保当出现故障的时候,已经落地到磁盘的数据不会丢失,并在重启的时候可以从操作记录中将数据恢复过来。5、Elasticsearch中使用一种称为倒排索引的结构,适用于快速的全文搜索。一个倒排索引由文档中所有不能重复词的列表构成,对于其中每个词,有一个包含它的文档列表。elasticsearch-倒排索引原理1、倒排索引采用ImmutableDesign,一旦生成,不可更改。Segment写入磁盘的过程相对耗时,所以借助文件系统缓存,Refresh时,先将Segment写入文件缓存中,以开放查询。2、Elasticsearch中使用一种称为倒排索引的结构,适用于快速的全文搜索。一个倒排索引由文档中所有不能重复词的列表构成,对于其中每个词,有一个包含它的文档列表。3、elasticsearch提供了translog来记录这些操作,结合oscachedsegments数据定时落盘来实现数据可靠性保证(flush)。文档被添加到buffer同时追加到translog:进行refresh操作,清空buffer,文档可被搜索但尚未flush到磁盘。4、如果Elasticsearch密钥库受密码保护,则必须先输入密钥库密码,然后才能为内置用户设置密码。为弹性用户设置密码后,引导密码不再有效,无法使用该命令。在某些情况下,分片副本的Lucene索引或事务日志可能会损坏。5、Elasticsearch的查询原理是将查询的关键词与倒排索引中的词条进行匹配,查询的关键词与倒排索引中的词条必须完全相同视为匹配,否则不匹配。这意味着在插入文档时是否进行分析和查询时是否进行分析将产生非常不同的结果。6、财务平台亿级数据量毫秒级查询优化之elasticsearch原理解析_wang123459的博客-CSDN博客_elasticsearch查询优化mysql底层B-tree支持矮胖,高胖的时候就很难受,说白了就是数据量多会增加IO操作。ES底层倒排索引。Elasticsearch一般情况下如果es服务正常启动,可以通过接口的方式获取elasticsearch版本信息:curlhttp://10.1:9200上述命令可以得到elasticsearch的服务状态和其他信息包括版本号。Elasticsearch是位于ElasticStack核心的分布式搜索和分析引擎。Logstash和Beats有助于收集、聚合和丰富您的数据并将其存储在Elasticsearch中。ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。Elasticsearch架构简单介绍如下。索引索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。你可以把索引看成关系型数据库的表。然而,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。如何用elasticsearch5.2实现全文索引1、安装ik分词器到elasticsearch很简单,它有个插件目录analysis-ik,和一个配置目录ik,分别拷贝到plugins和conf目录就可以了。2、ES使用倒序索引来加速全文索引。一个倒序索引由两部分组成:如果我们想要搜索quickbrown,我们仅仅只需要找每一个term出现的文档即可。如下图:每一个文档都匹配到了,但是第一个比第二个要匹配的多。3、每次将文本类型数据插入Elasticsearch索引时,都会对其进行分析,然后存储在反向索引中。根据分析器的配置方式,这会影响您的搜索功能,因为分析器也适用于全文搜索。

ElasticSearch性能优化实践(JVM调优+ES调优)

近一年内对公司的 ELK 日志系统做过性能优化,也对 SkyWalking 使用的 ES 存储进行过性能优化,在此做一些总结。本篇主要是讲 ES 在 ELK 架构中作为日志存储时的性能优化方案。 随着接入ELK的应用越来越多, 每日新增索引约 230 个,新增 document 约 3000万到 5000万 。 每日上午和下午是日志上传高峰期,在 Kibana 上查看日志,发现问题: (1) 日志会有 5-40 分钟的延迟 (2) 有很多日志丢失,无法查到 数据先是存放在 ES 的内存 buffer,然后执行 refresh 操作写入到操作系统的内存缓存 os cache,此后数据就可以被搜索到。 所以,日志延迟可能是我们的数据积压在 buffer 中没有进入 os cache 。 查看日志发现很多 write 拒绝执行的情况 从日志中可以看出 ES 的 write 线程池已经满负荷,执行任务的线程已经达到最大16个线程,而200容量的队列也已经放不下新的task。 查看线程池的情况也可以看出 write 线程池有很多写入的任务 所以我们需要优化 ES 的 write 的性能。 ES 的优化分为很多方面,我们要根据使用场景考虑对 ES 的要求。 根据个人实践经验,列举三种不同场景下的特点 : 这三类场景的特点如下: 关于实时性 可以从三方面进行优化:JVM性能调优、ES性能调优、控制数据来源 可以从三方面进行优化:JVM 性能调优、ES 性能调优、控制数据来源 第一步是 JVM 调优。 因为 ES 是依赖于 JVM 运行,没有合理的设置 JVM 参数,将浪费资源,甚至导致 ES 很容易 OOM 而崩溃。 (1) 查看 GC 日志 (2) 使用 jstat 看下每秒的 GC 情况 用下面几种方式都可查看新、老年代内存大小 (1) 使用 jstat -gc pid 查看 Eden 区、老年代空间大小 (2) 使用 jmap -heap pid 查看 Eden 区、老年代空间大小 (3) 查看 GC 日志中的 GC 明细 上面的几种方式都查询出,新生代总内存约1081M,即1G左右;老年代总内存为19864000K,约19G。新、老比例约1:19,出乎意料。 这真是一个容易踩坑的地方。 如果没有显示设置新生代大小,JVM 在使用 CMS 收集器时会自动调参,新生代的大小在没有设置的情况下是通过计算得出的,其大小可能与 NewRatio 的默认配置没什么关系而与 ParallelGCThreads 的配置有一定的关系。 所以: 新生代大小有不确定性,最好配置 JVM 参数 -XX:NewSize、-XX:MaxNewSize 或者 -xmn ,免得遇到一些奇怪的 GC,让人措手不及。 新生代过小,老年代过大的影响 32G 的内存,分配 20G 给堆内存是不妥当的,所以调整为总内存的50%,即16G。 修改 elasticsearch 的 jvm.options 文件 设置要求: 因为指定新生代空间大小,导致 JVM 自动调参只分配了 1G 内存给新生代。 修改 elasticsearch 的 jvm.options 文件,加上 老年代则自动分配 16G-8G=8G 内存,新生代老年代的比例为 1:1。修改后每次 Young GC 频率更低,且每次 GC 后只有少数数据会进入老年代。 ES默认使用的垃圾回收器是:老年代(CMS)+ 新生代(ParNew)。如果是JDK1.9,ES 默认使用G1垃圾回收器。 因为使用的是 JDK1.8,所以并未切换垃圾回收器。后续如果再有性能问题再切换G1垃圾回收器,测试是否有更好的性能。 优化前 每秒打印一次 GC 数据。可以看出,年轻代增长速度很快,几秒钟年轻代就满了,导致 Young GC 触发很频繁,几秒钟就会触发一次。而每次 Young GC 很大可能有存活对象进入老年代,而且,存活对象多的时候(看上图中第一个红框中的old gc数据),有(51.44-51.08)/100 * 19000M = 约68M。每次进入老年代的对象较多,加上频繁的 Young GC,会导致新老年代的分代模式失去了作用,相当于老年代取代了新生代来存放近期内生成的对象。当老年代满了,触发 Full GC,存活的对象也会很多,因为这些对象很可能还是近期加入的,还存活着,所以一次 Full GC 回收对象不多。而这会恶性循环,老年代很快又满了,又 Full GC,又残留一大部分存活的,又很容易满了,所以导致一直频繁 Full GC。 优化后 每秒打印一次 GC 数据。可以看出,新生代增长速度慢了许多,至少要60秒才会满,如上图红框中数据,进入老年代的对象约(15.68-15.60)/100 * 10000 = 8M,非常的少。所以要很久才会触发一次 Full GC 。而且等到 Full GC 时,老年代里很多对象都是存活了很久的,一般都是不会被引用,所以很大一部分会被回收掉,留一个比较干净的老年代空间,可以继续放很多对象。 ES 启动后,运行14个小时 优化前 Young GC 每次的时间是不长的,从上面监控数据中可以看出每次GC时长 1467.995/27276 约等于 0.05秒。那一秒钟有多少时间实在处理Young GC ? 计算公式:1467秒/ (60秒×60分 14小时)= 约0.028秒,也就是100秒中就有2.8秒在Young GC,也就是有2.8S的停顿,这对性能还是有很大消耗的。同时也可以算出多久一次Young GC, 方程是: 60秒×60分*14小时/ 27276次 = 1次/X秒,计算得出X = 0.54,也就是0.54秒就会有一次Young GC,可见 Young GC 频率非常频繁。 优化后 Young GC 次数只有修改前的十分之一,Young GC 时间也是约八分之一。Full GC 的次数也是只有原来的八分之一,GC 时间大约是四分之一。 GC 对系统的影响大大降低,性能已经得到很大的提升。 上面已经分析过ES作为日志存储时的特性是:高并发写、读少、接受30秒内的延时、可容忍部分日志数据丢失。 下面我们针对这些特性对ES进行调优。 本人整理了一下数据写入的底层原理 refresh ES 接收数据请求时先存入 ES 的内存中,默认每隔一秒会从内存 buffer 中将数据写入操作系统缓存 os cache,这个过程叫做 refresh; 到了 os cache 数据就能被搜索到(所以我们才说 ES 是近实时的,因为1s 的延迟后执行 refresh 便可让数据被搜索到) fsync translog 会每隔5秒或者在一个变更请求完成之后执行一次 fsync 操作,将 translog 从缓存刷入磁盘,这个操作比较耗时,如果对数据一致性要求不是跟高时建议将索引改为异步,如果节点宕机时会有5秒数据丢失; flush ES 默认每隔30分钟会将 os cache 中的数据刷入磁盘同时清空 translog 日志文件,这个过程叫做 flush。 merge ES 的一个 index 由多个 shard 组成,而一个 shard 其实就是一个 Lucene 的 index ,它又由多个 segment 组成,且 Lucene 会不断地把一些小的 segment 合并成一个大的 segment ,这个过程被称为 段merge 。执行索引操作时, ES会先生成小的segment ,ES 有离线的逻辑对小的 segment 进行合并,优化查询性能。但是合并过程中会消耗较多磁盘 IO,会影响查询性能。 为了保证不丢失数据,就要保护 translog 文件的安全: 该方式提高数据安全性的同时, 降低了一点性能. ==> 频繁地执行 fsync 操作, 可能会产生阻塞导致部分操作耗时较久. 如果允许部分数据丢失, 可设置异步刷新 translog 来提高效率,还有降低 flush 的阀值,优化如下: 写入 Lucene 的数据,并不是实时可搜索的,ES 必须通过 refresh 的过程把内存中的数据转换成 Lucene 的完整 segment 后,才可以被搜索。 默认1秒后,写入的数据可以很快被查询到,但势必会产生大量的 segment,检索性能会受到影响。所以,加大时长可以降低系统开销。对于日志搜索来说,实时性要求不是那么高,设置为5秒或者10s;对于SkyWalking,实时性要求更低一些,我们可以设置为30s。 设置如下: index.merge.scheduler.max_thread_count 控制并发的 merge 线程数,如果存储是并发性能较好的 SSD,可以用系统默认的 max(1, min(4, availableProcessors / 2)),当节点配置的 cpu 核数较高时,merge 占用的资源可能会偏高,影响集群的性能,普通磁盘的话设为1,发生磁盘 IO 堵塞。设置max_thread_count 后,会有 max_thread_count + 2 个线程同时进行磁盘操作,也就是设置为 1 允许3个线程。 设置如下: 该方式可对已经生成的索引做修改,但是对于后续新建的索引不生效,所以我们可以制作 ES 模板,新建的索引按模板创建索引。 因为我们的业务日志是按天维度创建索引,索引名称示例:user-service-prod-2020.12.12,所以用通配符 202 ..*匹配对应要创建的业务日志索引。 前文已经提到过,write 线程池满负荷,导致拒绝任务,而有的数据无法写入。 而经过上面的优化后,拒绝的情况少了很多,但是还是有拒绝任务的情况。 所以我们还需要优化write线程池。 从 prometheus 监控中可以看到线程池的情况: 为了更直观看到ES线程池的运行情况,我们安装了 elasticsearch_exporter 收集 ES 的指标数据到 prometheus,再通过 grafana 进行查看。 经过上面的各种优化,拒绝的数据量少了很多,但是还是存在拒绝的情况,如下图: write 线程池如何设置: 参考: ElasticSearch线程池 write 线程池采用 fixed 类型的线程池,也就是核心线程数与最大线程数值相同。线程数默认等于 cpu 核数,可设置的最大值只能是 cpu 核数加1,也就是16核CPU,能设置的线程数最大值为17。 优化的方案: config/elasticsearch.yml文件增加配置 优化后效果 Swap 交换分区 : 参考: ElasticSearch官方解释为什么要禁用交换内存 有三种方式可以实现 ES 不使用Swap分区 执行命令 可以临时禁用 Swap 内存,但是操作系统重启后失效 执行下列命令 正常情况下不会使用 Swap,除非紧急情况下才会 Swap。 config/elasticsearch.yml 文件增加配置 分片 索引的大小取决于分片与段的大小,分片过小,可能导致段过小,进而导致开销增加;分片过大可能导致分片频繁 Merge,产生大量 IO 操作,影响写入性能。 因为我们每个索引的大小在15G以下,而默认是5个分片,没有必要这么多,所以调整为3个。 分片的设置我们也可以配置在索引模板。 副本数 减少集群副本分片数,过多副本会导致 ES 内部写扩大。副本数默认为1,如果某索引所在的1个节点宕机,拥有副本的另一台机器拥有索引备份数据,可以让索引数据正常使用。但是数据写入副本会影响写入性能。对于日志数据,有1个副本即可。对于大数据量的索引,可以设置副本数为0,减少对性能的影响。 分片的设置我们也可以配置在索引模板。 有的应用1天生成10G日志,而一般的应用只有几百到1G。一天生成10G日志一般是因为部分应用日志使用不当,很多大数量的日志可以不打,比如大数据量的列表查询接口、报表数据、debug 级别日志等数据是不用上传到日志服务器,这些 即影响日志存储的性能,更影响应用自身性能 。 优化后的两周内ELK性能良好,没有使用上的问题: 参考

如何用elasticsearch5.2实现全文索引

一、ElasticSearch是什么?ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎。能够达到实时搜索,稳定,可靠,快速,安装使用方便,零配置和完全免费。我们先说说ES的基本概念。1、索引(Index)ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。2、类型(Type)类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。3、文档(Document)文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。4、映射(Mapping)ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。5、集群(Cluster)ES集群是一个或多个节点的集合,它们共同存储了整个数据集,并提供了联合索引以及可跨所有节点的搜索能力。多节点组成的集群拥有冗余能力,它可以在一个或几个节点出现故障时保证服务的整体可用性。集群靠其独有的名称进行标识,默认名称为“elasticsearch”。节点靠其集群名称来决定加入哪个ES集群,一个节点只能属一个集群。如果不考虑冗余能力等特性,仅有一个节点的ES集群一样可以实现所有的存储及搜索功能。6、节点(Node)运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。7、分片(Shard)和副本(Replica)ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。ES可自动在节点间按需要移动shard,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。OK,上面把ES相关的基本概念及原理大致说明了下,那么ES到底是怎么实现全文检索的呢?Elasticsearch实现全文检索,首先要确定分词器,ES默认有很多分词器,可参考官方文档。了解分词器主要是怎么实现的。一般中文分词器使用第三方的ik分词器、mmsegf分词器和paoding分词器,最初可能构建于lucene,后来移植于ES。目前我们在最新版的ES中,使用的是IK分词。安装ik分词器到elasticsearch很简单,它有个插件目录analysis-ik,和一个配置目录ik, 分别拷贝到plugins和conf目录就可以了。当你有大量的文本数据时,ES均会将其进行分词并将这些词语保存在索引中,当输入关键词进行查询时,索引就会起到作用,查找对应的相同的查询词,从而实现全文检索。当然这个过程是很吃内存的哦。

深入研究查询Elasticsearch,过滤查询和全文搜索

或如何了解缺少哪些官方文件 如果我不得不用一个短语来描述Elasticsearch,我会说: 目前,Elasticsearch在十大最受欢迎的开源技术中。 公平地说,它结合了许多本身并不独特的关键功能,但是,当结合使用时,它可以成为最佳的搜索引擎/分析平台。 更准确地说,由于以下功能的结合,Elasticsearch变得如此流行: · 搜索相关性评分 · 全文搜索 · 分析(汇总) · 无模式(对数据模式无限制),NoSQL,面向文档 · 丰富的数据类型选择 · 水平可扩展 · 容错的 通过与Elasticsearch进行合作,我很快意识到,官方文档看起来更像是所谓文档的"挤压"。 我不得不在Google上四处搜寻,并且大量使用stackowerflow,所以我决定编译这篇文章中的所有信息。 在本文中,我将主要撰写有关查询/搜索Elasticsearch集群的文章。 您可以通过多种不同的方式来实现大致相同的结果,因此,我将尝试说明每种方法的利弊。 更重要的是,我将向您介绍两个重要的概念-查询和过滤器上下文-在文档中没有很好地解释。 我将为您提供一组规则,以决定何时使用哪种方法更好。 在阅读本文后,如果我只想让您记住一件事,那就是: 当我们谈论Elasticsearch时,总会有一个相关性分数。 相关性分数是严格的正浮点数,表示每个文档满足搜索标准的程度。 该分数是相对于分配的最高分数的,因此,分数越高,文档与搜索条件的相关性越好。 但是,过滤器和查询是您在编写查询之前应该能够理解的两个不同概念。 一般来说,过滤器上下文是一个"是/否"选项,其中每个文档都与查询匹配或不匹配。 一个很好的例子是SQL WHERE,后面是一些条件。 SQL查询总是返回严格符合条件的行。 SQL查询无法返回歧义结果。 另一方面,Elasticsearch查询上下文显示了每个文档与您的需求的匹配程度。 为此,查询使用分析器查找最佳匹配。 经验法则是将过滤器用于: · 是/否搜索 · 搜索精确值(数字,范围和关键字) 将查询用于: · 结果不明确(某些文档比其他文档更适合) · 全文搜索 此外,Elasticsearch将自动缓存过滤器的结果。 在第1部分和第2部分中,我将讨论查询(可以转换为过滤器)。 请不要将结构化和全文与查询和过滤器混淆-这是两件事。 结构化查询也称为术语级查询,是一组查询方法,用于检查是否应选择文档。 因此,在很多情况下,没有真正必要的相关性评分-文档匹配或不匹配(尤其是数字)。 术语级查询仍然是查询,因此它们将返回分数。 名词查询 Term Query 返回字段值与条件完全匹配的文档。 查询一词是SQL select * from table_name where column_name =...的替代方式 名词查询直接进入倒排索引,这可以使其快速进行。 在处理文本数据时,最好仅将term用于keyword字段。 名词查询默认情况下在查询上下文中运行,因此,它将计算分数。 即使所有返回的文档的分数相同,也将涉及其他计算能力。 带有过滤条件的 名词 查询 如果我们想加速名词查询并使其得到缓存,则应将其包装在constant_score过滤器中。 还记得经验法则吗? 如果您不关心相关性得分,请使用此方法。 现在,该查询没有计算任何相关性分数,因此,它更快。 而且,它是自动缓存的。 快速建议-对文本字段使用匹配而不是名词。 请记住,名词查询直接进入倒排索引。名词查询采用您提供的值并按原样搜索它,这就是为什么它非常适合查询未经任何转换存储的keyword字段。 多名词查询 Terms query 如您所料,多名词查询使您可以返回至少匹配一个确切名词的文档。 多名词查询在某种程度上是SQL select * from table_name where column_name is in...的替代方法 重要的是要了解,Elasticsearch中的查询字段可能是一个列表,例如{“ name”:[“ Odin”,“ Woden”,“ Wodan”]}。如果您执行的术语查询包含以下一个或多个,则该记录将被匹配-它不必匹配字段中的所有值,而只匹配一个。 与名词查询相同,但是这次您可以在查询字段中指定多少个确切术语。 您指定必须匹配的数量-一,二,三或全部。 但是,此数字是另一个数字字段。 因此,每个文档都应包含该编号(特定于该特定文档)。 返回查询字段值在定义范围内的文档。 等价于SQL select * from table_name where column_name is between... 范围查询具有自己的语法: · gt 大于 · gte 大于或等于 · lt 小于 · lte 小于或等于 一个示例,该字段的值应≥4且≤17 范围查询也可以很好地与日期配合使用。 正则表达式查询返回其中字段与您的正则表达式匹配的文档。 如果您从未使用过正则表达式,那么我强烈建议您至少了解一下它是什么以及何时可以使用它。 Elasticsearch的正则表达式是Lucene的正则表达式。 它具有标准的保留字符和运算符。 如果您已经使用过Python的re软件包,那么在这里使用它应该不是问题。 唯一的区别是Lucene的引擎不支持^和$等锚运算符。 您可以在官方文档中找到regexp的完整列表。 除正则表达式查询外,Elsticsearch还具有通配符和前缀查询。从逻辑上讲,这两个只是regexp的特殊情况。 不幸的是,我找不到关于这三个查询的性能的任何信息,因此,我决定自己对其进行测试,以查看是否发现任何重大差异。 在比较使用rehexp和通配符查询时,我找不到性能上的差异。如果您知道有什么不同,请给我发消息。 由于Elasticsearch是无模式的(或没有严格的模式限制),因此当不同的文档具有不同的字段时,这是一种很常见的情况。 结果,有很多用途来了解文档是否具有某些特定字段。 全文查询适用于非结构化文本数据。 全文查询利用了分析器。 因此,我将简要概述Elasticsearch的分析器,以便我们可以更好地分析全文查询。 每次将文本类型数据插入Elasticsearch索引时,都会对其进行分析,然后存储在反向索引中。根据分析器的配置方式,这会影响您的搜索功能,因为分析器也适用于全文搜索。 分析器管道包括三个阶段: 总有一个令牌生成器和零个或多个字符和令牌过滤器。 1)字符过滤器按原样接收文本数据,然后可能在对数据进行标记之前对其进行预处理。 字符过滤器用于: · 替换与给定正则表达式匹配的字符 · 替换与给定字符串匹配的字符 · 干净的HTML文字 2)令牌生成器将字符过滤器(如果有)之后接收到的文本数据分解为令牌。 例如,空白令牌生成器只是将文本分隔为空白(这不是标准的)。 因此,Wednesday is called after Woden, 将被拆分为[Wednesday, is, called, after, Woden.]。 有许多内置标记器可用于创建自定义分析器。 删除标点符号后,标准令牌生成器将使用空格分隔文本。 对于绝大多数语言来说,这是最中立的选择。 除标记化外,标记化器还执行以下操作: · 跟踪令牌顺序, · 注释每个单词的开头和结尾 · 定义令牌的类型 3)令牌过滤器对令牌进行一些转换。您可以选择将许多不同的令牌过滤器添加到分析器中。一些最受欢迎的是: · 小写 · 词干(存在多种语言!) · 删除重复 · 转换为等效的ASCII · 模式的解决方法 · 令牌数量限制 · 令牌的停止列表(从停止列表中删除令牌) 标准分析器是默认分析器。 它具有0个字符过滤器,标准令牌生成器,小写字母和停止令牌过滤器。 您可以根据需要组成自定义分析器,但是内置分析器也很少。 语言分析器是一些最有效的即用型分析器,它们利用每种语言的细节来进行更高级的转换。 因此,如果您事先知道数据的语言,建议您从标准分析器切换为数据的一种语言。 全文查询将使用与索引数据时使用的分析器相同的分析器。更准确地说,您查询的文本将与搜索字段中的文本数据进行相同的转换,因此两者处于同一级别。 匹配查询是用于查询文本字段的标准查询。 我们可以将匹配查询称为名词查询的等效项,但适用于文本类型字段(而在处理文本数据时,名词应仅用于关键字类型字段)。 默认情况下,传递给查询参数的字符串(必需的一个)将由与应用于搜索字段的分析器相同的分析器处理。 除非您自己使用analyzer参数指定分析器。 当您指定要搜索的短语时,将对其进行分析,并且结果始终是一组标记。默认情况下,Elasticsearch将在所有这些标记之间使用OR运算符。这意味着至少应该有一场比赛-更多的比赛虽然会得分更高。您可以在运算符参数中将其切换为AND。在这种情况下,必须在文档中找到所有令牌才能将其返回。 如果要在OR和AND之间输入某些内容,则可以指定minimum_should_match参数,该参数指定应匹配的子句数。 可以数字和百分比指定。 模糊参数(可选)可让您忽略错别字。 Levenshtein距离用于计算。 如果您将匹配查询应用于关键字keyword字段,则其效果与词条查询相同。 更有趣的是,如果将存储在反向索引中的令牌的确切值传递给term查询,则它将返回与匹配查询完全相同的结果,但是会更快地返回到反向索引。 与匹配相同,但顺序和接近度很重要。 匹配查询不了解序列和接近度,因此,只有通过其他类型的查询才能实现词组匹配。 match_phrase查询具有slop参数(默认值为0),该参数负责跳过术语。 因此,如果您指定斜率等于1,则短语中可能会省略一个单词。 多重比对查询的功能与比对相同,唯一的不同是多重比对适用于多个栏位 · 字段名称可以使用通配符指定 · 默认情况下,每个字段均加权 · 每个领域对得分的贡献都可以提高 · 如果没有在fields参数中指定任何字段,那么将搜索所有符合条件的字段 有多种类型的multi_match。 我不会在这篇文章中描述它们,但是我将解释最受欢迎的: best_fields类型(默认值)更喜欢在一个字段中找到来自搜索值的令牌的结果,而不是将搜索的令牌分配到不同字段中的结果。 most_fields与best_fields类型相反。 phrase类型的行为与best_fields相同,但会搜索与match_phrase类似的整个短语。 我强烈建议您查阅官方文档,以检查每个字段的得分计算准确度。 复合查询将其他查询包装在一起。 复合查询: · 结合分数 · 改变包装查询的行为 · 将查询上下文切换到过滤上下文 · 以上任意一项 布尔查询将其他查询组合在一起。 这是最重要的复合查询。 布尔查询使您可以将查询上下文中的搜索与过滤器上下文搜索结合在一起。 布尔查询具有四个可以组合在一起的出现(类型): · must或"必须满足该条款" · should或"如果满足条款,则对相关性得分加分" · 过滤器filter或"必须满足该条款,但不计算相关性得分" · must_not或“与必须相反”,不会有助于相关度得分 必须和应该→查询上下文 过滤器和must_not→过滤器上下文 对于那些熟悉SQL的人,必须为AND,而应为OR运算符。 因此,必须满足must子句中的每个查询。 对于大多数查询,提升查询与boost参数相似,但并不相同。 增强查询将返回与肯定子句匹配的文档,并降低与否定子句匹配的文档的得分。 如我们在术语查询示例中先前看到的,constant_score查询将任何查询转换为相关性得分等于boost参数(默认值为1)的过滤器上下文。 让我知道是否您想阅读另一篇文章,其中提供了所有查询的真实示例。 我计划在Elasticsearch上发布更多文章,所以不要错过。 你已经读了很长的内容,所以如果你阅读到这里: 综上所述,Elasticsearch符合当今的许多用途,有时很难理解什么是最佳工具。 如果不需要相关性分数来检索数据,请尝试切换到过滤器上下文。 另外,了解Elasticsearch的工作原理也至关重要,因此,我建议您始终了解分析器的功能。 Elasticsearch中还有许多其他查询类型。 我试图描述最常用的。 我希望你喜欢它。 (本文翻译自kotartemiy u2714ufe0f的文章《Deep Dive into Querying Elasticsearch. Filter vs Query. Full-text search》,参考:https://towardsdatascience.com/deep-pe-into-querying-elasticsearch-filter-vs-query-full-text-search-b861b06bd4c0)

全文搜索之MySQL与ElasticSearch搜索引擎

MySQL支持全文索引和搜索功能。在MySQL中可以在CHAR、VARCHAR或TEXT列使用FULLTETXT来创建全文索引。 FULLTEXT索引主要用MATCH()...AGAINST语法来实现搜索: MySQL的全文搜索存在以下局限: 通常来说MySQL自带的全文搜索使用起来局限性比较大,性能和功能都不太成熟,主要适用于小项目,大项目还是建议使用elasticsearch来做全文搜索。 ElasticSearch是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据,以下简称ES。 Elasticsearch 在 Apache Lucene 的基础上开发而成,Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名,是 Elastic Stack 的核心组件。Elastic Stack 是适用于数据采集、充实、存储、分析和可视化的一组开源工具。 Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据中心,再通过分词控制器去将对应的数据分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。 由于ES是基于RESTfull Web接口的,因此我们直接按照惯例传递JSON参数调用接口即可实现增删改查,并且不需要我们做额外的管理操作就可以直接索引文档,ES已经内置了所有的缺省操作,可以自动帮我们定义类型。 再次执行PUT,会对库中已有的id为1的数据进行覆盖,每修改一次_version字段的版本号就会加1。 默认搜索会返回前10个结果: 返回的几个关键词: 查询字符串搜索,可以像传递URL参数一样传递查询语句。 精确查询: 全文搜索: 以上两种方法都需要考虑数据更改后如何与ES进行同步。

ElasticSearch存储

使用ElasticSearch快一年了,自认为相关API使用的还比较6,产品提的一些搜索需求实现起来都从心应手;但是前几天同事的一个问题直接将我打回到小白,同事问了句:“ ElasticSearch的索引是怎么存储的?删除文档和更新文档是怎么实现的? ”,当时我就懵逼了,说了句得查一下,好尴尬...... 回想起来发现自己从来都没有深入了解过这些细节,于是便觉得非常有必要对ElasticSearch的文档存储做一次深入的了解,知其然不知其所以然对于我们来说是远远不够的,在ElasticSearch中,文档( Document )存储的介质分为内存和硬盘两种: 同时,ElasticSearch进程自身的运行也需要内存空间,必须保证ElasticSearch进程有充足的运行时内存。为了使ElasticSearch引擎达到最佳性能,必须合理分配有限的内存和硬盘资源。 ElasticSearch引擎把文档数据写入到倒排索引( Inverted Index )的数据结构中,倒排索引建立的是分词( Term )和文档( Document )之间的映射关系,在倒排索引中,数据是面向词( Term )而不是面向文档( Document )的。 举个栗子,假设我们有两个文档,每个文档的content域包含如下内容: 1. The quick brown fox jumped over the lazy dog 2. Quick brown foxes leap over lazy dogs in summer 文档和词之间的关系如下图: 字段值被分析之后,存储在倒排索引中,倒排索引存储的是分词( Term )和文档( Doc )之间的关系,简化版的倒排索引如下图: 从图中可以看出,倒排索引有一个词条的列表,每个分词在列表中是唯一的,记录着词条出现的次数,以及包含词条的文档。实际中ElasticSearch引擎创建的倒排索引比这个复杂得多。 段是倒排索引的组成部分,倒排索引是由段( Segment )组成的,段存储在硬盘( Disk )文件中。 索引段不是实时更新的,这意味着,段在写入硬盘之后,就不再被更新。在删除文档时,ElasticSearch引擎把已删除的文档的信息存储在一个单独的文件中,在搜索数据时,ElasticSearch引擎首先从段中执行查询,再从查询结果中过滤被删除的文档 。这意味着,段中存储着被删除的文档,这使得段中含有”正常文档“的密度降低。 多个段可以通过段合并(Segment Merge)操作把“已删除”的文档将从段中物理删除,把未删除的文档合并到一个新段中,新段中没有”已删除文档“,因此,段合并操作能够提高索引的查找速度 ;但是,段合并是IO密集型操作,需要消耗大量的硬盘IO。 在ElasticSearch中,大多数查询都需要从硬盘文件(索引的段数据存储在硬盘文件中)中获取数据;因此, 在全局配置文件elasticsearch.yml 中,把结点的路径(Path)配置为性能较高的硬盘,能够提高查询性能 。默认情况下,ElasticSearch使用基于安装目录的相对路径来配置结点的路径,安装目录由属性path.home显示,在home path下,ElasticSearch自动创建config,data,logs和plugins目录,一般情况下不需要对结点路径单独配置。结点的文件路径配置项: path.data:设置ElasticSearch结点的索引数据保存的目录,多个数据文件使用逗号隔开。 例如,path.data: /path/to/data1,/path/to/data2 ; path.work:设置ElasticSearch的临时文件保存的目录; 映射参数index决定ElasticSearch引擎是否对文本字段执行分析操作,也就是说分析操作把文本分割成一个一个的分词,也就是标记流( Token Stream ),把分词编入索引,使分词能够被搜索到: 1) 当index为analyzed时,该字段是分析字段,ElasticSearch引擎对该字段执行分析操作,把文本分割成分词流,存储在倒排索引中,使其支持全文搜索。 2)当index为not_analyzed时,该字段不会被分析,ElasticSearch引擎把原始文本作为单个分词存储在倒排索引中,不支持全文搜索,但是支持词条级别的搜索;也就是说,字段的原始文本不经过分析而存储在倒排索引中,把原始文本编入索引,在搜索的过程中,查询条件必须全部匹配整个原始文本。 3)当index为no时,该字段不会被存储到倒排索引中,不会被搜索到。 字段的原始值是否被存储到倒排索引,是由映射参数store决定的,默认值是false,也就是,原始值不存储到倒排索引中。 映射参数index和store的区别在于: store用于获取(Retrieve)字段的原始值,不支持查询,可以使用投影参数fields,对stroe属性为true的字段进行过滤,只获取(Retrieve)特定的字段,减少网络负载; index用于查询(Search)字段,当index为analyzed时,对字段的分词执行全文查询;当index为not_analyzed时,字段的原始值作为一个分词,只能对字段的原始文本执行词条查询; 如果设置字段的index属性为not_analyzed,原始文本将作为单个分词,其最大长度跟UTF8 编码有关,默认的最大长度是32766Bytes(约32KB),如果字段的文本超过该限制,那么ElasticSearch将跳过( Skip )该文档,并在Response中抛出异常消息: operation[607]: index returned 400 _index: ebrite _type: events _id: 76860 _version: 0 error: Type: illegal_argument_exception Reason: "Document contains at least one immense term in field="event_raw" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: "[112, 114,... 115]...", original message: bytes can be at most 32766 in length; got 35100" CausedBy:Type: max_bytes_length_exceeded_exception Reason: "bytes can be at most 32766 in length; got 35100" 可以在字段中设置ignore_above属性,该属性值指的是字符数量,而不是字节数量;由于一个UTF8字符最多占用3个字节,因此,可以设置 “ignore_above”:10000 这样,超过30000字节之后的字符将会被分析器忽略,单个分词( Term )的最大长度是30000Bytes。 The value for ignore_above is the character count, but Lucene counts bytes. If you use UTF-8 text with many non-ASCII characters, you may want to set the limit to 32766 / 3 = 10922 since UTF-8 characters may occupy at most 3 bytes. 默认情况下,大多数字段被索引之后,能够被搜索到。 倒排索引是由一个有序的词条列表构成的,每一个词条在列表中都是唯一存在的,通过这种数据存储模式,你可以很快查找到包含某一个词条的文档列表 。 但是,排序和聚合操作采用相反的数据访问模式,这两种操作不是查找词条以发现文档,而是查找文档,以发现字段中包含的词条。ElasticSearch使用列式存储实现排序和聚合查询。 文档值( doc_values )是存储在硬盘上的数据结构,在索引时( index time )根据文档的原始值创建,文档值是一个列式存储风格的数据结构,非常适合执行存储和聚合操作,除了字符类型的分析字段之外,其他字段类型都支持文档值存储。默认情况下,字段的文档值存储是启用的,除了字符类型的分析字段之外。如果不需要对字段执行排序或聚合操作,可以禁用字段的文档值,以节省硬盘空间。 字符类型的分析字段,不支持文档值(doc_values),但支持fielddata数据结构。fielddata数据结构存储在JVM的堆内存中。相比文档值(数据存储在硬盘上),fielddata字段(数据存储在内存中)的查询性能更高。默认情况下,ElasticSearch引擎在第一次对字段执行聚合或排序查询时(query-time),创建fielddata数据结构;在后续的查询请求中,ElasticSearch引擎使用fielddata数据结构以提高聚合和排序的查询性能。 在ElasticSearch中,倒排索引的各个段( segment )的数据存储在硬盘文件上,从整个倒排索引的段中读取字段数据之后,ElasticSearch引擎首先反转词条和文档之间的关系,创建文档和词条之间的关系,即创建顺排索引,然后把顺排索引存储在JVM的堆内存中。把倒排索引加载到fielddata结构是一个非常消耗硬盘IO资源的过程。因此,数据一旦被加载到内存,最好保持在内存中,直到索引段( segment )的生命周期结束。 默认情况下,倒排索引的每个段( segment ),都会创建相应的fielddata结构,以存储字符类型的分析字段值,但是,需要注意的是,分配的JVM堆内存是有限的,Fileddata把数据存储在内存中,会占用过多的JVM堆内存,甚至耗尽JVM赖以正常运行的内存空间,反而会降低ElasticSearch引擎的查询性能。 fielddata会消耗大量的JVM内存,因此,尽量为JVM设置大的内存,不要为不必要的字段启用fielddata存储。通过format参数控制是否启用字段的fielddata特性,字符类型的分析字段,fielddata的默认值是paged_bytes,这就意味着,默认情况下,字符类型的分析字段启用fielddata存储。一旦禁用fielddata存储,那么字符类型的分析字段将不再支持排序和聚合查询。 loading属性控制fielddata加载到内存的时机,可能的值是lazy,eager和eager_global_ordinals,默认值是lazy。 lazy:fielddata只在需要时加载到内存,默认情况下,在第一次搜索时,fielddata被加载到内存中;但是,如果查询一个非常大的索引段(Segment),lazy加载方式会产生较大的时间延迟。 eager:在倒排索引的段可用之前,其数据就被加载到内存,eager加载方式能够减少查询的时间延迟,但是,有些数据可能非常冷,以至于没有请求来查询这些数据,但是冷数据依然被加载到内存中,占用紧缺的内存资源。 eager_global_ordinals:按照global ordinals积极把fielddata加载到内存。 ElasticSearch使用 JAVA_OPTS 环境变量( Environment Variable )启动JVM进程,在 JAVA_OPTS 中,最重要的配置是: -Xmx参数控制分配给JVM进程的最大内存,-Xms参数控制分配给JVM进程的最小内存 。(在ElasticSearch启动命令后面可以通过参数方式配置,如: /usr/local/elasticsearch/bin/elasticsearch -d --Xmx=10g --Xms=10g )通常情况下,使用默认的配置就能满足工程需要。 ES_HEAP_SIZE 环境变量控制分配给JVM进程的堆内存( Heap Memory )大小,顺排索引( fielddata )的数据存储在堆内存( Heap Memory )中。 大多数应用程序尝试使用尽可能多的内存,并尽可能把未使用的内存换出,但是,内存换出会影响ElasticSearch引擎的查询性能,推荐启用内存锁定,禁用ElasticSearch内存的换进换出。 在全局配置文档 elasticsearch.yml 中,设置 bootstrap.memory_lock 为ture,这将锁定ElasticSearch进程的内存地址空间,阻止ElasticSearch内存被OS换出( Swap out )。 通过学习,算是对ElasticSearch索引存储及更新有了一个较深的了解,至少能让我从容去面对同事的提问,但与此同时给我敲响了警钟,在使用一门技术的同时,更应该去了解它具体的原理,而不仅仅是停留在使用级别;在学习的路上,我们仍需要更加努力......

Elasticsearch数据迁移与集群容灾

本文讨论如何跨集群迁移ES数据以及如何实现ES的同城跨机房容灾和异地容灾。 在ES的生产实践中,往往会遇到以下问题: 根据业务需求,存在以下场景: 如果是第一种场景,数据迁移过程中可以停止写入,可以采用诸如elasticsearch-dump、logstash、reindex、snapshot等方式进行数据迁移。实际上这几种工具大体上可以分为两类: 如果是第二种场景,数据迁移过程中旧集群不能停止写入,需要根据实际的业务场景解决数据一致性的问题: 下面介绍一下在旧集群可以停止写入的情况下进行数据迁移的几种工具的用法。 elasticsearch-dump是一款开源的ES数据迁移工具,github地址: https://github.com/taskrabbit/elasticsearch-dump 以下操作通过elasticdump命令将集群x.x.x.1中的companydatabase索引迁移至集群x.x.x.2。注意第一条命令先将索引的settings先迁移,如果直接迁移mapping或者data将失去原有集群中索引的配置信息如分片数量和副本数量等,当然也可以直接在目标集群中将索引创建完毕后再同步mapping与data logstash支持从一个ES集群中读取数据然后写入到另一个ES集群,因此可以使用logstash进行数据迁移,具体的配置文件如下: 上述配置文件将源ES集群的所有索引同步到目标集群中,当然可以设置只同步指定的索引,logstash的更多功能可查阅logstash官方文档 logstash 官方文档 . reindex是Elasticsearch提供的一个api接口,可以把数据从一个集群迁移到另外一个集群。 snapshot api是Elasticsearch用于对数据进行备份和恢复的一组api接口,可以通过snapshot api进行跨集群的数据迁移,原理就是从源ES集群创建数据快照,然后在目标ES集群中进行恢复。需要注意ES的版本问题: 如果旧集群不能停止写入,此时进行在线数据迁移,需要保证新旧集群的数据一致性。目前看来,除了官方提供的CCR功能,没有成熟的可以严格保证数据一致性的在线数据迁移方法。此时可以从业务场景出发,根据业务写入数据的特点选择合适的数据迁移方案。 一般来说,业务写入数据的特点有以下几种: 下面来具体分析不同的写入数据的特点下,该如何选择合适的数据迁移方式。 在日志或者APM的场景中,数据都是时序数据,一般索引也都是按天创建的,当天的数据只会写入当前的索引中。此时,可以先把存量的不再写入的索引数据一次性同步到新集群中,然后使用logstash或者其它工具增量同步当天的索引,待数据追平后,把业务对ES的访问切换到新集群中。 具体的实现方案为: add only的数据写入方式,可以按照数据写入的顺序(根据_doc进行排序,如果有时间戳字段也可以根据时间戳排序)批量从旧集群中拉取数据,然后再批量写入新集群中;可以通过写程序,使用用scroll api 或者search_after参数批量拉取增量数据,再使用bulk api批量写入。 使用scroll拉取增量数据: 上述操作可以每分钟执行一次,拉起前一分钟新产生的数据,所以数据在旧集群和新集群的同步延迟为一分钟。 使用search_after批量拉取增量数据: 上述操作可以根据需要自定义事件间隔执行,每次执行时修改search_after参数的值,获取指定值之后的多条数据;search_after实际上相当于一个游标,每执行一次向前推进,从而获取到最新的数据。 使用scroll和search_after的区别是: 另外,如果不想通过写程序迁移旧集群的增量数据到新集群的话,可以使用logstash结合scroll进行增量数据的迁移,可参考的配置文件如下: 使用过程中可以根据实际业务的需求调整定时任务参数schedule以及scroll相关的参数。 业务场景如果是写入ES时既有追加,又有存量数据的更新,此时比较重要的是怎么解决update操作的数据同步问题。对于新增的数据,可以采用上述介绍的增量迁移热索引的方式同步到新集群中。对于更新的数据,此时如果索引有类似于updateTime的字段用于标记数据更新的时间,则可以通过写程序或者logstash,使用scroll api根据updateTime字段批量拉取更新的增量数据,然后再写入到新的集群中。 可参考的logstash配置文件如下: 实际应用各种,同步新增(add)的数据和更新(update)的数据可以同时进行。但是如果索引中没有类似updateTime之类的字段可以标识出哪些数据是更新过的,目前看来并没有较好的同步方式,可以采用CCR来保证旧集群和新集群的数据一致性。 如果业务写入ES时既有新增(add)数据,又有更新(update)和删除(delete)数据,可以采用6.5之后商业版X-pack插件中的CCR功能进行数据迁移。但是使用CCR有一些限制,必须要注意: 具体的使用方式如下: 如果业务是通过中间件如kafka把数据写入到ES, 则可以使用如下图中的方式,使用logstash消费kafka的数据到新集群中,在旧集群和新集群数据完全追平之后,可以切换到新集群进行业务的查询,之后再对旧的集群下线处理。 使用中间件进行同步双写的优点是: 当然,双写也可以使用其他的方式解决,比如自建proxy,业务写入时向proxy写入,proxy把请求转发到一个或者多个集群中,但是这种方式存在以下问题: 随着业务规模的增长,业务侧对使用的ES集群的数据可靠性、集群稳定性等方面的要求越来越高,所以要比较好的集群容灾方案支持业务侧的需求。 如果是公司在自建IDC机房内,通过物理机自己搭建的ES集群,在解决跨机房容灾的时候,往往会在两个机房 部署两个ES集群,一主一备,然后解决解决数据同步的问题;数据同步一般有两种方式,一种方式双写,由业务侧实现双写保证数据一致性,但是双写对业务侧是一个挑战,需要保证数据在两个集群都写成功才能算成功。另外一种方式是异步复制,业务侧只写主集群,后台再把数据同步到备集群中去,但是比较难以保证数据一致性。第三种方式是通过专线打通两个机房,实现跨机房部署,但是成本较高。 因为数据同步的复杂性,云厂商在实现ES集群跨机房容灾的时候,往往都是通过只部署一个集群解决,利用ES自身的能力同步数据。国外某云厂商实现跨机房部署ES集群的特点1是不强制使用专用主节点,如上图中的一个集群,只有两个节点,既作为数据节点也作为候选主节点;主分片和副本分片分布在两个可用区中,因为有副本分片的存在,可用区1挂掉之后集群仍然可用,但是如果两个可用区之间网络中断时,会出现脑裂的问题。如下图中使用三个专用主节点,就不会存在脑裂的问题了。 但是如果一个地域没有三个可用区怎么办呢,那就只能在其中一个可用区中放置两个专用主节点了,如国内某云厂商的解决方案: 但是重建节点的过程还是存在问题的,如上图中,集群本身的quorum应该为2,可用区1挂掉后,集群中只剩一个专用主节点,需要把quorum参数(discovery.zen.minimum_master_nodes)调整为1后集群才能够正常进行选主,等挂掉的两个专用主节点恢复之后,需要再把quorum参数(discovery.zen.minimum_master_nodes)调整为2,以避免脑裂的发生。 当然还是有可以把无法选主和脑裂这两个可能发生的问题规避掉的解决方案,如下图中国内某云厂商的解决思路: 创建双可用区集群时,必须选择3个或者5个专用主节点,后台会在一个隐藏的可用区中只部署专用主节点;方案的优点1是如果一个可用区挂掉,集群仍然能够正常选主,避免了因为不满足quorum法定票数而无法选主的情况;2是因为必须要选择三个或5个专用主节点,也避免了脑裂。 想比较一主一备两个集群进行跨机房容灾的方式,云厂商通过跨机房部署集群把原本比较复杂的主备数据同步问题解决了,但是,比较让人担心的是,机房或者可用区之间的网络延迟是否会造成集群性能下降。这里针对腾讯云的双可用区集群,使用标准的benchmark工具对两个同规格的单可用区和双可用区集群进行了压测,压测结果如下图所示: 从压测结果的查询延时和写入延时指标来看,两种类型的集群并没有明显的差异,这主要得益与云上底层网络基础设施的完善,可用区之间的网络延迟很低。 类似于同城跨机房容灾,异地容灾一般的解决思路是在异地两个机房部署一主一备两个集群。业务写入时只写主集群,再异步地把数据同步到备集群中,但是实现起来会比较复杂,因为要解决主备集群数据一致性的问题,并且跨地域的话,网络延迟会比较高;还有就是,当主集群挂掉之后,这时候切换到备集群,可能两边数据还没有追平,出现不一致,导致业务受损。当然,可以借助于kafka等中间件实现双写,但是数据链路增加了,写入延迟也增加了,并且kafka出现问题,故障可能就是灾难性的了。 一种比较常见的异步复制方法是,使用snapshot备份功能,定期比如每个小时在主集群中执行一次备份,然后在备集群中进行恢复,但是主备集群会有一个小时的数据延迟。以腾讯云为例,腾讯云的ES集群支持把数据备份到对象存储COS中,因为可以用来实现主备集群的数据同步,具体的操作步骤可以参考 https://cloud.tencent.com/document/product/845/19549 。 在6.5版本官方推出了CCR功能之后,集群间数据同步的难题就迎刃而解了。可以利用CCR来实现ES集群的异地容灾: CCR是类似于数据订阅的方式,主集群为Leader, 备集群为Follower, 备集群以pull的方式从主集群拉取数据和写请求;在定义好Follwer Index时,Follwer Index会进行初始化,从Leader中以snapshot的方式把底层的segment文件全量同步过来,初始化完成之后,再拉取写请求,拉取完写请求后,Follwer侧进行重放,完成数据的同步。CCR的优点当然是因为可以同步UPDATE/DELETE操作,数据一致性问题解决了,同步延时也减小了。 另外,基于CCR可以和前面提到的跨机房容灾的集群结合,实现两地多中心的ES集群。在上海地域,部署有多可用区集群实现跨机房的高可用,同时在北京地域部署备集群作为Follwer利用CCR同步数据,从而在集群可用性上又向前走了一步,既实现了同城跨机房容灾,又实现了跨地域容灾。 但是在出现故障时需要把集群的访问从上海切换到北京时,会有一些限制,因为CCR中的Follwer Index是只读的,不能写入,需要切换为正常的索引才能进行写入,过程也是不可逆的。不过在业务侧进行规避,比如写入时使用新的正常的索引,业务使用别名进行查询,当上海地域恢复时,再反向的把数据同步回去。 现在问题就是保证上海地域集群数据的完整性,在上海地域恢复后,可以在上海地域新建一个Follower Index,以北京地域正在进行写的索引为Leader同步数据,待数据完全追平后,再切换到上海地域进行读写,注意切换到需要新建Leader索引写入数据。 数据同步过程如下所示: 1.上海主集群正常提供服务,北京备集群从主集群Follow数据 2.上海主集群故障,业务切换到北京备集群进行读写,上海主集群恢复后从北京集群Follow数据

Elasticsearch解决问题之道——请亮出你的DSL

0、引言 在业务开发中,我们往往会陷入开发的细枝末节之中,而忽略了事物的本源。 经常有同学问到: 等等等等….. 以上的看似复杂的问题,如果转换成DSL,清楚的写出来,梳理清楚问题的来龙去脉,问题就自然解决了一大半。 所以,请亮出你的dsl,不论什么语言的检索,转换到es查询都是sql查询,在es中对应dsl语法,es再拆解比如:分词match_phrase拆解成各term组合,最终传给lucene处理。 亮出你的dsl,确保编程里的实现和你的kibana或者head插件一致是非常重要、很容易被忽视的工作。 如果对dsl拆解不理解,那就再 加上 profile:true或者explain:true拆解结果一目了然。 维基百科定义:领域特定语言(英语:domain-specific language、DSL)指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。 Elasticsearch提供基于JSON的完整查询DSL来定义查询。 将Query DSL视为查询的AST(抽象语法树),由两种类型的子句组成: 1、叶子查询子句 叶查询子句查找特定字段中的特定值,例如匹配,术语或范围查询。 这些查询可以单独使用。 2、复合查询子句 复合查询子句可以组合其他叶子或复合查询,用于以逻辑方式组合多个查询(例如bool或dis_max查询),或更改其行为(例如constant_score查询)。 给个例子,一看就明白。 看到这里,可能会有人着急了:“我X,这不是官网定义吗?再写一遍有意思吗?” 引用一句鸡汤话,“再显而易见的道理,在中国,至少有一亿人不知道”。同样的,再显而易见的问题,在Elasticsearch技术社区也会有N多人提问。 基础认知不怕重复,可怕的是对基础的专研、打磨、夯实。 Elasticsearch相关的核心操作,广义上可做如下解读,不一定涵盖全,仅抛砖引玉,说明DSL的重要性。 从大到小。 集群的管理,一般我们会使用Kibana或者第三方工具Head插件、cerebro工具、elastic-hq工具。 基本上硬件的(磁盘、cpu、内存)使用率、集群的 健康 状态都能一目了然。 但基础的DSL会更便捷,便于细粒度分析问题。 如:集群状态查询: 如:节点热点线程查看: 如:集群分片分配情况查看: 索引生命周期是一直强调的概念,主要指索引的“生、老、病、死”的全过程链条的管理。 创建索引我们优先使用较单纯index更灵活的template模板。 创建索引类似Mysql的创建表的操作,提前设计好表结构对应ES是提前设计好M app ing非常重要。 两个维度: 举例: 如:索引清理缓存。 如:某原因导致分片重新分配,_recovery查看分片分配状态。 高版本的索引生命周期管理推荐使用:ILM功能。 这个是大家再熟悉不过的了。 举例: 删除数据包括:指定id删除 delete和批量删除delete_by_query(满足给定条件)。 更新操作。包括:指定id的update/upsert或者批量更新update_by_query。 这是ES的重头戏。包含但不限于: 1、支持精确匹配查询的:term、range、exists、wildcard、prefix、fuzzy等。 2、支持全文检索的:match、match_phrase、query_string、multi_match等 1、Bucketing分桶聚合 举例:最常用的terms就类似Mysql group by功能。2、Metric计算聚合 举例:类比Mysql中的: MIN, MAX, SUM 操作。3、Pipeline针对聚合结果聚合 举例:bucket_script实现类似Mysql的group by 后having的操作。 留给大家 结合 业务场景思考添加。 这里把开头提到的几个问题逐一解答一下。 实际Mysql业务中,我们一般是先验证sql没有问题,再写业务代码。 实际ES业务中,也一样,先DSL确认没有问题,再写业务代码。 写完java或者python后,打印DSL,核对是否完全一致。 不一致的地方基本就是结果和预期不一致的原因所在。 第一步:借助analyzer API分析查询语句和待查询document分词结果。 这个API的重要性,再怎么强调都不为过。 第二步:可以借助profile:true查看细节。第三步:核对match_phrase词序的原理。 6.3版本后已经支持sql,如果不会写,可以借助translate 如下API翻译一下。 不够精确,但足够参考用了,需要根据业务细节微调。 当然,还是 建议 ,从业务出发,自己写DSL。 从大往小,逐步细化排解 END 公众号 ( zhisheng )里回复 面经、ES、Flink、 Spring、Java、Kafka、监控 等关键字可以查看更多关键字对应的文章 1、《从0到1学习Flink》—— Apache Flink 介绍 2、《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门 3、《从0到1学习Flink》—— Flink 配置文件详解 4、《从0到1学习Flink》—— Data Source 介绍 5、《从0到1学习Flink》—— 如何自定义 Data Source ? 6、《从0到1学习Flink》—— Data Sink 介绍 7、《从0到1学习Flink》—— 如何自定义 Data Sink ? 8、《从0到1学习Flink》—— Flink Data transformation(转换) 9、《从0到1学习Flink》—— 介绍 Flink 中的 Stream Windows 10、《从0到1学习Flink》—— Flink 中的几种 Time 详解 11、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 ElasticSearch 12、《从0到1学习Flink》—— Flink 项目如何运行? 13、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 Kafka 14、《从0到1学习Flink》—— Flink JobManager 高可用性配置 15、《从0到1学习Flink》—— Flink parallelism 和 Slot 介绍 16、《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL 17、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 RabbitMQ 18、《从0到1学习Flink》—— 你上传的 jar 包藏到哪里去了 19、大数据“重磅炸弹”——实时计算框架 Flink 20、《Flink 源码解析》—— 源码编译运行 21、为什么说流处理即未来? 22、OPPO数据中台之基石:基于Flink SQL构建实数据仓库 23、流计算框架 Flink 与 Storm 的性能对比 24、Flink状态管理和容错机制介绍 25、原理解析 | Apache Flink 结合 Kafka 构建端到端的 Exactly-Once 处理 26、Apache Flink 是如何管理好内存的? 27、《从0到1学习Flink》——Flink 中这样管理配置,你知道? 28、《从0到1学习Flink》——Flink 不可以连续 Split(分流)? 29、Flink 从0到1学习—— 分享四本 Flink 的书和二十多篇 Paper 论文 30 、360深度实践:Flink与Storm协议级对比 31、Apache Flink 1.9 重大特性提前解读 32、如何基于Flink+TensorFlow打造实时智能异常检测平台?只看这一篇就够了 33、美团点评基于 Flink 的实时数仓建设实践 34、Flink 灵魂两百问,这谁顶得住? 35、一文搞懂 Flink 的 Exactly Once 和 At Least Once 36、你公司到底需不需要引入实时计算引擎?

京东面试题:ElasticSearch深度分页解决方案

Elasticsearch 是一个实时的分布式搜索与分析引擎,在使用过程中,有一些典型的使用场景,比如分页、遍历等。 在使用关系型数据库中,我们被告知要注意甚至被明确禁止使用深度分页,同理,在 Elasticsearch 中,也应该尽量避免使用深度分页。 这篇文章主要介绍 Elasticsearch 中分页相关内容! 在ES中,分页查询默认返回最顶端的10条匹配hits。 如果需要分页,需要使用from和size参数。 一个基本的ES查询语句是这样的: 上面的查询表示从搜索结果中取第100条开始的10条数据。 「那么,这个查询语句在ES集群内部是怎么执行的呢?」 在ES中,搜索一般包括两个阶段,query 和 fetch 阶段,可以简单的理解,query 阶段确定要取哪些doc,fetch 阶段取出具体的 doc。 如上图所示,描述了一次搜索请求的 query 阶段:· 在上面的例子中,coordinating node 拿到 (from + size) * 6 条数据,然后合并并排序后选择前面的 from + size 条数据存到优先级队列,以便 fetch 阶段使用。 另外,各个分片返回给 coordinating node 的数据用于选出前 from + size 条数据,所以,只需要返回唯一标记 doc 的 _id 以及用于排序的 _score 即可,这样也可以保证返回的数据量足够小。 coordinating node 计算好自己的优先级队列后,query 阶段结束,进入 fetch 阶段。 query 阶段知道了要取哪些数据,但是并没有取具体的数据,这就是 fetch 阶段要做的。 上图展示了 fetch 过程: coordinating node 的优先级队列里有 from + size 个 _doc _id ,但是,在 fetch 阶段,并不需要取回所有数据,在上面的例子中,前100条数据是不需要取的,只需要取优先级队列里的第101到110条数据即可。 需要取的数据可能在不同分片,也可能在同一分片,coordinating node 使用 「multi-get」 来避免多次去同一分片取数据,从而提高性能。 「这种方式请求深度分页是有问题的:」 我们可以假设在一个有 5 个主分片的索引中搜索。当我们请求结果的第一页(结果从 1 到 10 ),每一个分片产生前 10 的结果,并且返回给 协调节点 ,协调节点对 50 个结果排序得到全部结果的前 10 个。 现在假设我们请求第 1000 页—结果从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果以外。然后协调节点对全部 50050 个结果排序最后丢弃掉这些结果中的 50040 个结果。 「对结果排序的成本随分页的深度成指数上升。」 「注意1:」 size的大小不能超过 index.max_result_window 这个参数的设置,默认为10000。 如果搜索size大于10000,需要设置 index.max_result_window 参数 「注意2:」 _doc 将在未来的版本移除,详见: Elasticsearch 的From/Size方式提供了分页的功能,同时,也有相应的限制。 举个例子,一个索引,有10亿数据,分10个 shards,然后,一个搜索请求,from=1000000,size=100,这时候,会带来严重的性能问题:CPU,内存,IO,网络带宽。 在 query 阶段,每个shards需要返回 1000100 条数据给 coordinating node,而 coordinating node 需要接收 10 * 1000 ,100 条数据,即使每条数据只有 _doc _id 和 _score ,这数据量也很大了? 「在另一方面,我们意识到,这种深度分页的请求并不合理,因为我们是很少人为的看很后面的请求的,在很多的业务场景中,都直接限制分页,比如只能看前100页。」 比如,有1千万粉丝的微信大V,要给所有粉丝群发消息,或者给某省粉丝群发,这时候就需要取得所有符合条件的粉丝,而最容易想到的就是利用 from + size 来实现,不过,这个是不现实的,这时,可以采用 Elasticsearch 提供的其他方式来实现遍历。 深度分页问题大致可以分为两类: 「下面介绍几个官方提供的深度分页方法」 我们可以把scroll理解为关系型数据库里的cursor,因此,scroll并不适合用来做实时搜索,而更适合用于后台批处理任务,比如群发。 这个分页的用法, 「不是为了实时查询数据」 ,而是为了 「一次性查询大量的数据(甚至是全部的数据」 )。 因为这个scroll相当于维护了一份当前索引段的快照信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。 但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。 不考虑排序的时候,可以结合 SearchType.SCAN 使用。 scroll可以分为初始化和遍历两部,初始化时将 「所有符合搜索条件的搜索结果缓存起来(注意,这里只是缓存的doc_id,而并不是真的缓存了所有的文档数据,取数据是在fetch阶段完成的)」 ,可以想象成快照。 在遍历时,从这个快照里取数据,也就是说,在初始化后,对索引插入、删除、更新数据都不会影响遍历结果。 「基本使用」 初始化指明 index 和 type,然后,加上参数 scroll,表示暂存搜索结果的时间,其它就像一个普通的search请求一样。 会返回一个 _scroll_id , _scroll_id 用来下次取数据用。 「遍历」 这里的 scroll_id 即 上一次遍历取回的 _scroll_id 或者是初始化返回的 _scroll_id ,同样的,需要带 scroll 参数。 重复这一步骤,直到返回的数据为空,即遍历完成。 「注意,每次都要传参数 scroll,刷新搜索结果的缓存时间」 。另外, 「不需要指定 index 和 type」 。 设置scroll的时候,需要使搜索结果缓存到下一次遍历完成, 「同时,也不能太长,毕竟空间有限。」 「优缺点」 缺点: 「优点:」 适用于非实时处理大量数据的情况,比如要进行数据迁移或者索引变更之类的。 ES提供了scroll scan方式进一步提高遍历性能,但是scroll scan不支持排序,因此scroll scan适合不需要排序的场景 「基本使用」 Scroll Scan 的遍历与普通 Scroll 一样,初始化存在一点差别。 需要指明参数: 「Scroll Scan与Scroll的区别」 如果你数据量很大,用Scroll遍历数据那确实是接受不了,现在Scroll接口可以并发来进行数据遍历了。 每个Scroll请求,可以分成多个Slice请求,可以理解为切片,各Slice独立并行,比用Scroll遍历要快很多倍。 上边的示例可以单独请求两块数据,最终五块数据合并的结果与直接scroll scan相同。 其中max是分块数,id是第几块。 Search_after 是 ES 5 新引入的一种分页查询机制,其原理几乎就是和scroll一样,因此代码也几乎是一样的。 「基本使用:」 第一步: 返回出的结果信息 : 上面的请求会为每一个文档返回一个包含sort排序值的数组。 这些sort排序值可以被用于 search_after 参数里以便抓取下一页的数据。 比如,我们可以使用最后的一个文档的sort排序值,将它传递给 search_after 参数: 若我们想接着上次读取的结果进行读取下一页数据,第二次查询在第一次查询时的语句基础上添加 search_after ,并指明从哪个数据后开始读取。 「基本原理」 es维护一个实时游标,它以上一次查询的最后一条记录为游标,方便对下一页的查询,它是一个无状态的查询,因此每次查询的都是最新的数据。 由于它采用记录作为游标,因此 「SearchAfter要求doc中至少有一条全局唯一变量(每个文档具有一个唯一值的字段应该用作排序规范)」 「优缺点」 「优点:」 「缺点:」 SEARCH_AFTER 不是自由跳转到任意页面的解决方案,而是并行滚动多个查询的解决方案。 分页方式性能优点缺点场景 from + size低灵活性好,实现简单深度分页问题数据量比较小,能容忍深度分页问题 scroll中解决了深度分页问题无法反应数据的实时性(快照版本)维护成本高,需要维护一个 scroll_id海量数据的导出需要查询海量结果集的数据 search_after高性能最好不存在深度分页问题能够反映数据的实时变更实现复杂,需要有一个全局唯一的字段连续分页的实现会比较复杂,因为每一次查询都需要上次查询的结果,它不适用于大幅度跳页查询海量数据的分页 参照:https://www.elastic.co/guide/en/elasticsearch/reference/master/paginate-search-results.html#scroll-search-results 在 7.* 版本中,ES官方不再推荐使用Scroll方法来进行深分页,而是推荐使用带PIT的 search_after 来进行查询; 从 7.* 版本开始,您可以使用 SEARCH_AFTER 参数通过上一页中的一组排序值检索下一页命中。 使用 SEARCH_AFTER 需要多个具有相同查询和排序值的搜索请求。 如果这些请求之间发生刷新,则结果的顺序可能会更改,从而导致页面之间的结果不一致。 为防止出现这种情况,您可以创建一个时间点(PIT)来在搜索过程中保留当前索引状态。 在搜索请求中指定PIT: 分别分页获取 1 - 10 , 49000 - 49010 , 99000 - 99010 范围各10条数据(前提10w条),性能大致是这样: 对于向前翻页,ES中没有相应API,但是根据官方说法(https://github.com/elastic/elasticsearch/issues/29449),ES中的向前翻页问题可以通过翻转排序方式来实现即: Scroll和 search_after 原理基本相同,他们都采用了游标的方式来进行深分页。 这种方式虽然能够一定程度上解决深分页问题。但是,它们并不是深分页问题的终极解决方案,深分页问题 「必须避免!!」 。 对于Scroll,无可避免的要维护 scroll_id 和 历史 快照,并且,还必须保证 scroll_id 的存活时间,这对服务器是一个巨大的负荷。 对于 Search_After ,如果允许用户大幅度跳转页面,会导致短时间内频繁的搜索动作,这样的效率非常低下,这也会增加服务器的负荷,同时,在查询过程中,索引的增删改会导致查询数据不一致或者排序变化,造成结果不准确。 Search_After 本身就是一种业务折中方案,它不允许指定跳转到页面,而只提供下一页的功能。 Scroll默认你会在后续将所有符合条件的数据都取出来,所以,它只是搜索到了所有的符合条件的 doc_id (这也是为什么官方推荐用 doc_id 进行排序,因为本身缓存的就是 doc_id ,如果用其他字段排序会增加查询量),并将它们排序后保存在协调节点(coordinate node),但是并没有将所有数据进行fetch,而是每次scroll,读取size个文档,并返回此次读取的最后一个文档以及上下文状态,用以告知下一次需要从哪个shard的哪个文档之后开始读取。 这也是为什么官方不推荐scroll用来给用户进行实时的分页查询,而是适合于大批量的拉取数据,因为它从设计上就不是为了实时读取数据而设计的。

ElasticSearch分页方案

"浅"分页是最简单的分页方案。es会根据查询条件在每一个DataNode分片中取出from+size条文档,然后在MasterNode中聚合、排序,再截取size-from的文档返回给调用方。当页数越靠后,也就是from+size越大,es需要读取的数据也就是越大,聚合和排序的时候处理的数据量也越大,此时会加大服务器CPU和内存的消耗。 其中,from定义了目标数据的偏移值,size定义当前返回的数目。默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。 在这里有必要了解一下from/size的原理: 因为es是基于分片的,假设有5个分片,from=100,size=10。则会根据排序规则从5个分片中各取回100条数据数据,然后汇总成500条数据后选择最后面的10条数据。 做过测试,越往后的分页,执行的效率越低。总体上会随着from的增加,消耗时间也会增加。而且数据量越大,就越明显! from+size查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。 为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式。 scroll 类似于sql中的cursor,使用scroll,每次只能获取一页的内容,然后会返回一个scroll_id。根据返回的这个scroll_id可以不断地获取下一页的内容,所以scroll并不适用于有跳页的情景。 scroll=5m表示设置scroll_id保留5分钟可用。 使用scroll必须要将from设置为0。 size决定后面每次调用_search搜索返回的数量 然后我们可以通过数据返回的_scroll_id读取下一页内容,每次请求将会读取下10条数据,直到数据读取完毕或者scroll_id保留时间截止: 注意:请求的接口不再使用索引名了,而是 _search/scroll,其中GET和POST方法都可以使用。 scroll删除 根据官方文档的说法,scroll的搜索上下文会在scroll的保留时间截止后自动清除,但是我们知道scroll是非常消耗资源的,所以一个建议就是当不需要了scroll数据的时候,尽可能快的把scroll_id显式删除掉。 清除指定的scroll_id: DELETE _search/scroll/DnF1ZXJ5VGhlbkZldGNo..... 清除所有的scroll: DELETE _search/scroll/_all scroll 的方式,官方的建议不用于实时的请求(一般用于数据导出),因为每一个 scroll_id 不仅会占用大量的资源,而且会生成历史快照,对于数据的变更不会反映到快照上。 search_after 分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。但是需要注意,因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。 为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _uid 作为全局唯一值,其实使用业务层的 id 也可以。 使用search_after必须要设置from=0。 这里我使用timestamp和_id作为唯一值排序。 我们在返回的最后一条数据里拿到sort属性的值传入到search_after。 使用sort返回的值搜索下一页: 4:修改默认分页限制值10000 可以使用下面的方式来改变ES默认深度分页的index.max_result_window 最大窗口值 curl -XPUT http://127.0.0.1:9200/my_index/_settings -d "{ "index" : { "max_result_window" : 500000}}" 其中my_index为要修改的index名,500000为要调整的新的窗口数。将该窗口调整后,便可以解决无法获取到10000条后数据的问题。 注意事项 通过上述的方式解决了我们的问题,但也引入了另一个需要我们注意的问题,窗口值调大了后,虽然请求到分页的数据条数更多了,但它是用牺牲更多的服务器的内存、CPU资源来换取的。要考虑业务场景中过大的分页请求,是否会造成集群服务的OutOfMemory问题。 修改最大限制值之后确实可以使from+size查询到更后面页的数据,但是每次查询得到的总数量最大任然是10000,要想获取大于1万的查询数据量,可以分两步查询,第一步使用scroll查询获取总数据量;第二部使用from+size查询每页的数据,并设置分页。这样即解决了from+size无法查询10000之后的数据,也解决了scroll无法跳页的问题。 使用scroll可能遇到的问题: Caused by: org.elasticsearch.ElasticsearchException: Trying to create too many scroll contexts. Must be less than or equal to: [500]. This limit can be set by changing the [search.max_open_scroll_context] setting. 这个报错是从es的日志文件中查出来的,大致意思是:尝试创建更多的scroll对象失败了,scroll对象总数量应该控制在500以内。可修改search.max_open_scroll_context的值来改变500这个阈值。 原因:通过scroll 深分页可知道,es服务端会在内存中生成一个scroll_id对象,并会为该值指定过期时间,翻页的时候使用scroll_id来获取下一页的数据。默认情况下,一个实例下面仅可以创建最多500个scroll上下文对象,也就是500个scroll_id。报此错误的原因就是创建scroll上下文对象失败,因为当前已经存在500个这样的对象了。 解决办法: 1:通过观察可以发现,即使不做任何的处理,过一会就又可以发起scroll请求了,这是因为时间超过了scroll生命周期时间,scroll对象自己死掉了一些。 2:按照提示说的,修改search.max_open_scroll_context的值 put http://{{es-host}}/_cluster/settings { } [图片上传失败...(image-4dc354-1583253824871)] 3:在使用完scroll_id之后立即调用删除接口,删除该scroll对象 删除单个scroll DELETE http://{{es-host}}/_search/scroll { } 删除所有scroll delete http://{{es-host}}/_search/scroll/_all

ElasticSearch查询流程详解

前面已经介绍了ElasticSearch的写入流程,了解了ElasticSearch写入时的分布式特性的相关原理。ElasticSearch作为一款具有强大搜索功能的存储引擎,它的读取是什么样的呢?读取相比写入简单的多,但是在使用过程中有哪些需要我们注意的呢?本篇文章会进行详细的分析。 在前面的文章我们已经知道ElasticSearch的读取分为两种GET和SEARCH。这两种操作是有一定的差异的,下面我们先对这两种核心的数据读取方式进行一一分析。 (图片来自官网) 以下是从主分片或者副本分片检索文档的步骤顺序: 注意: 在协调节点有个http_server_worker线程池。收到读请求后它的具体过程为: 数据节点上有一个get线程池。收到了请求后,处理过程为: 注意: get过程会加读锁。处理realtime选项,如果为true,则先判断是否有数据可以刷盘,然后调用Searcher进行读取。Searcher是对IndexSearcher的封装在早期realtime为true则会从tranlog中读取,后面只会从index的lucene读取了。即实时的数据只在lucene之中。 对于Search类请求,ElasticSearch请求是查询lucene的Segment,前面的写入详情流程也分析了,新增的文档会定时的refresh到磁盘中,所以搜索是属于近实时的。而且因为没有文档id,你不知道你要检索的文档在哪个分配上,需要将索引的所有的分片都去搜索下,然后汇总。ElasticSearch的search一般有两个搜索类型 所有的搜索系统一般都是两阶段查询: 第一阶段查询到匹配的docID,第二阶段再查询DocID对应的完整文档。这种在ElasticSearch中称为query_then_fetch,另一种就是一阶段查询的时候就返回完整Doc,在ElasticSearch中叫query_and_fetch,一般第二种适用于只需要查询一个Shard的请求。因为这种一次请求就能将数据请求到,减少交互次数,二阶段的原因是需要多个分片聚合汇总,如果数据量太大那么会影响网络传输效率,所以第一阶段会先返回id。 除了上述的这两种查询外,还有一种三阶段查询的情况。 搜索里面有一种算分逻辑是根据TF和DF来计算score的,而在普通的查询中,第一阶段去每个Shard中独立查询时携带条件算分都是独立的,即Shard中的TF和DF也是独立的。虽然从统计学的基础上数据量多的情况下,每一个分片的TF和DF在整体上会趋向于准确。但是总会有情况导致局部的TF和DF不准的情况出现。 ElasticSearch为了解决这个问题引入了DFS查询。 比如DFS_query_then_fetch,它在每次查询时会先收集所有Shard中的TF和DF值,然后将这些值带入请求中,再次执行query_then_fetch,这样算分的时候TF和DF就是准确的,类似的有DFS_query_and_fetch。这种查询的优势是算分更加精准,但是效率会变差。 另一种选择是用BM25代替TF/DF模型。 在ElasticSearch7.x,用户没法指定以下两种方式: DFS_query_and_fetch 和 query_and_fetch 。 注:这两种算分的算法模型在《ElasticSearch实战篇》有介绍: 这里query_then_fetch具体的搜索的流程图如下: (图片来自官网) 查询阶段包含以下四个步骤: 以上就是ElasticSearch的search的详细流程,下面会对每一步进行进一步的说明。 协调节点处理query请求的线程池为: http_server_work 负责该解析功能的类为: org.elasticsearch.rest.action.search.RestSearchAction 主要将restquest的参数封装成SearchRequest 这样SearchRequest请求发送给TransportSearchAction处理 将索引涉及到的shard列表或者有跨集群访问相关的shard列表合并 如果有多个分片位于同一个节点,仍然会发送多次请求 shardsIts为搜索涉及的所有分片,而shardRoutings.nextOrNull()会从分片的所有副本分片选出一个分片来请求。 onShardSuccess对收集到的结果进行合并,这里需要检查所有的请求是否都已经有了回复。 然后才会判断要不要进行executeNextPhase 当返回结果的分片数等于预期的总分片数时,协调节点会进入当前Phase的结束处理,启动下一个阶段Fetch Phase的执行。onPhaseDone()会executeNextPhase来执行下一个阶段。 当触发了executeNextPhase方法将触发fetch阶段 上一步的executeNextPhase方法触发Fetch阶段,Fetch阶段的起点为FetchSearchPhase#innerRun函数,从查询阶段的shard列表中遍历,跳过查询结果为空的 shard。其中也会封装一些分页信息的数据。 使用了countDown多线程工具,fetchResults存储某个分片的结果,每收到一个shard的数据就countDoun一下,当都完毕后,触发finishPhase。接着会进行下一步: CountedCollector: finishPhase: 执行字段折叠功能,有兴趣可以研究下。即ExpandSearchPhase模块。ES 5.3版本以后支持的Field Collapsing查询。通过该类查询可以轻松实现按Field值进行分类,每个分类获取排名前N的文档。如在菜单行为日志中按菜单名称(用户管理、角色管理等)分类,获取每个菜单排名点击数前十的员工。用户也可以按Field进行Aggregation实现类似功能,但Field Collapsing会更易用、高效。 ExpandSearchPhase执行完了,就返回给客户端结果了。 处理数据节点请求的线程池为:search 根据前面的两个阶段,数据节点主要处理协调节点的两类请求:query和fetch 这里响应的请求就是第一阶段的query请求 executeQueryPhase: executeQueryPhase会执行loadOrExecuteQueryPhase方法 这里判断是否从缓存查询,默认启用缓存,缓存的算法默认为LRU,即删除最近最少使用的数据。如果不启用缓存则会执行queryPhase.execute(context);底层调用lucene进行检索,并且进行聚合。 关键点: ElasticSearch查询分为两类,一类为GET,另一类为SEARCH。它们使用场景不同。 本文主要分析了ElasticSearch分布式查询主体流程,并未对lucene部分进行分析,有兴趣的可以自行查找相关资料。

elasticsearch的自动发现节点机制是怎么实现的,原理是怎样

1、Gossip 是一种去中心化、容错而又最终一致性的绝妙算法, 其收敛性不但得到证明还具有指数级的收敛速度。2、使用 Gossip 的系统可以很容易的把 Server 扩展到更多的节点, 满足弹性扩展轻而易举。3、唯一的缺点是收敛是最终一致性, 不适应那些强一致性的场景, 比如 2PC。

Elasticsearch 倒排索引

之前我们已经了解过,Elasticsearch 是一个基于 Lucene 实现的分布式全文检索引擎,其实 Elasticsearch 倒排索引就是 Lucene 的倒排索引。数据检索是 ES 的一项核心功能,它的底层实现也是离不开倒排索引的,通过倒排索引技术可以提高数据的检索效率,理解倒排索引的原理很重要。 那什么是倒排索引,我们该如何理解它呢? 我们能进行数据检索的前提条件是,已经创建好了索引库,并给里边添加了文档数据。所以我们可以按照 创建索引库 、 添加文档 、 数据检索 这个顺序来认识倒排索引。 首先是创建索引库,我们之前已经安装好了 IK 分词器,这里我们创建一个 test 索引,它只有一个 content 字段,添加文档时字段的分词模式是 ik_max_word ,检索时关键字的分词模式是 ik_smart : 字段的分词模式会影响最终生成的倒排索引。不了解分词器的可以参考 Elasticsearch 中文分词器插件 。 创建好了索引,我们来添加一条文档数据: 添加文档数据时,ES 会根据字段的分词模式将字段的值拆分成多个 词条 (Term)(或者称作词项),创建索引库时我们指定了 content 字段分词模式为 ik_max_word ,则会生成如下的词条: 接下来就是建立倒排索引了,在这之前我们先了解两个概念 词条字典 (Term Dictionary)、 倒排列表 (Posting List): ES 的倒排索引就是由 词条字典 和 倒排列表 两部分组成的。如下就是一个简易版的倒排索引,倒排列表项只有词条对应的文档 id: 一个词条对应一个倒排索引项。ES 会给每个字段都建立一个倒排索引。 我们再添加一条文档数据: 根据上边的原理,最终 content 字段的倒排索引会被更新成如下结构: 前边已经添加了文档数据,同时也生成了倒排索引,接下来就是检索数据了。在这之前还有一个知识点需要了解,那就是 词条索引 (Term Index),词条索引一般只存储各个 词条 的前缀(第一个字符),它和字条字典对应。之所以需要词条索引,是因为 词条字典 一般都很大,不适合保存在内存中而是存储在磁盘中,检索数据时根据关键字的前缀匹配到词条索引,再根据词条索引定位到关键字在倒排索引的词条字典中大致的位置,然后进一步在词条字典中通过二分查找定位到具体的词条,这样避免了直接遍历词条字典来点位词条,大幅减少了磁盘的读取,提高了效率。 定位到了词条,就能在倒排索引中找到对应的倒排列表项,进而就知道了对应的文档 id,有了文档 id 自然也就找到了文档,这也就是 ES 检索数据大致的原理。 如下我们查询包含 十二 的文档数据: 由于我们创建索引库时指定了检索时关键字的分词模式是 ik_smart ,所以 十二 被分词后还是 十二 ,再结合上边的原理,以 十二 为关键字最终可以查询到 id 为 1、2 的文档数据:这篇最好能结合 Elasticsearch 中文分词器插件 一起看,这样能更容易理解些。 新手上路,不合理的地方还望大佬指点。

从查询重写角度理解elasticsearch的高亮原理

一、高亮的一些问题 elasticsearch提供了三种高亮方式,前面我们已经简单的了解了elasticsearch的高亮原理; 高亮处理跟实际使用查询类型有十分紧密的关系,其中主要的一点就是muti term 查询的重写,例如wildcard、prefix等,由于查询本身和高亮都涉及到查询语句的重写,如果两者之间的重写机制不同,那么就可能会碰到以下情况 相同的查询语句, 使用unified和fvh得到的高亮结果是不同的,甚至fvh Highlighter无任何高亮信息返回; 二、数据环境 elasticsearch 8.0 三、muti term查询重写简介 所谓muti term查询就是查询中并不是明确的关键字,而是需要elasticsearch重写查询语句,进一步明确关键字;以下查询会涉及到muti term查询重写; 以上查询都支持rewrite参数,最终将查询重写为bool查询或者bitset; 查询重写主要影响以下几方面 重写需要抓取哪些关键字以及抓取的数量; 抓取关键字的相关性计算方式; 查询重写支持以下参数选项 constant_score,默认值,如果需要抓取的关键字比较少,则重写为bool查询,否则抓取所有的关键字并重写为bitset;直接使用boost参数作为文档score,一般term level的查询的boost默认值为1; constant_score_boolean,将查询重写为bool查询,并使用boost参数作为文档的score,受到indices.query.bool.max_clause_count 限制,所以默认最多抓取1024个关键字; scoring_boolean,将查询重写为bool查询,并计算文档的相对权重,受到indices.query.bool.max_clause_count 限制,所以默认最多抓取1024个关键字; top_terms_blended_freqs_N,抓取得分最高的前N个关键字,并将查询重写为bool查询;此选项不受indices.query.bool.max_clause_count 限制;选择命中文档的所有关键字中权重最大的作为文档的score; top_terms_boost_N,抓取得分最高的前N个关键字,并将查询重写为bool查询;此选项不受indices.query.bool.max_clause_count 限制;直接使用boost作为文档的score; top_terms_N,抓取得分最高的前N个关键字,并将查询重写为bool查询;此选项不受indices.query.bool.max_clause_count 限制;计算命中文档的相对权重作为评分; 三、wildcard查询重写分析 我们通过elasticsearch来查看一下以下查询语句的重写逻辑; 通过查询使用的字段映射类型构建WildCardQuery,并使用查询语句中配置的rewrite对应的MultiTermQuery.RewriteMethod; 根据查询语句中配置的rewrite,查找对应的MultiTermQuery.RewriteMethod,由于我们没有在wildcard查询语句中设置rewrite参数,这里直接返回null; WildCardQuery继承MultiTermQuery,直接调用rewrite方法进行重写,由于我们没有在wildcard查询语句中设置rewrite参数,这里直接使用默认的CONSTANT_SCORE_REWRITE; 可以看到CONSTANT_SCORE_REWRITE是直接使用的匿名类,rewrite方法返回的是MultiTermQueryConstantScoreWrapper的实例; 在以下方法中,首先会得到查询字段对应的所有term集合; 然后通过 query.getTermsEnum获取跟查询匹配的所有term集合; 最后根据collectTerms调用的返回值决定是否构建bool查询还是bit set; 调用collectTerms默认只会提取查询命中的16个关键字; 通过以上分析wildcard查询默认情况下,会提取字段中所有命中查询的关键字; 四、fvh Highlighter中wildcard的查询重写 在muti term query中,提取查询关键字是高亮逻辑一个很重要的步骤; 我们使用以下高亮语句,分析以下高亮中提取查询关键字过程中的查询重写; 默认情况下只有匹配的字段才会进行高亮,这里构建CustomFieldQuery; 通过调用flatten方法得到重写之后的flatQueries,然后将每个提取的关键字重写为BoostQuery; 由于WildCardQuery是MultiTermQuery的子类,所以在flatten方法中最终直接使用MultiTermQuery.TopTermsScoringBooleanQueryRewrite进行查询重写,这里的top N是MAX_MTQ_TERMS = 1024; 这里首先计算设置的size和getMaxSize(默认值1024, IndexSearcher.getMaxClauseCount())计算最终提取的命中关键字数量,这里最终是1024个; 这里省略了传入collectTerms的TermCollector匿名子类的实现,其余最终提取关键字数量有关; 这里首先获取查询字段对应的所有term集合,然后获取所有的与查询匹配的term集合,最终通过传入的collector提取关键字; 这里通过控制最终提取匹配查询的关键字的数量不超过maxSize; 通过以上分析可以看到,fvh Highlighter对multi term query的重写,直接使用MultiTermQuery.TopTermsScoringBooleanQueryRewrite,并限制只能最多提取查询关键字1024个; 五、重写可能导致的高亮问题原因分析 经过以上对查询和高亮的重写过程分析可以知道,默认情况下 query阶段提取的是命中查询的所有的关键字,具体行为可以通过rewrite参数进行定制; Highlight阶段提取的是命中查询的关键字中的前1024个,具体行为不受rewrite参数的控制; 如果查询的字段是大文本字段,导致字段的关键字很多,就可能会出现查询命中的文档的关键字不在前1024个里边,从而导致明明匹配了文档,但是却没有返回高亮信息; 六、解决方案

ElasticSearch倒排索引及其原理

倒排索引采用Immutable Design,一旦生成,不可更改。 Segment写入磁盘的过程相对耗时,所以借助文件系统缓存,Refresh时,先将Segment写入文件缓存中,以开放查询。但为了保证数据不会丢失,所以在创建索引时,会同时写Tansaction Log,类似操作日志。 在ES进行Refresh时,Index Buffer会被清空,Transaction Log不会清空。 Flush操作: Flush触发条件: 随着索引的不断创建,Segments文件会越来越多。ES会自动进行merge操作,将多个segments文件合并,以提高查询效率。但Merge是很重的操作,对磁盘有频繁IO操作,会对系统性能有影响。 除此之外,我们还可以通过api强制merge: 我们还可以通过配置refresh的频率(refresh_interval),来适当减少Segments产生的数量。

Elasticsearch -- 集群内的原理

首先理解三个概念 1)集群内的节点共同承担数据和负载的压力。 2)当有节点加入或者移出集群时,集群会重新平均分配所有的数据。 1)主节点负责集群内的所有变更(如增加、删除节点,增加、删除索引等) 2)主节点并不需要涉及到文档级别的变更和搜索 3)任何节点都可以成为主节点 4)每个节点都知道任意文档所处的位置,当用户请求时无论请求哪个节点都能直接将请求转发给实际存储文档的节点 5)无论用户请求哪个节点,它都能负责从个个包含我们所需文档的各个节点收集回数据并发给客户端,对这一切都是透明的 1)一个分片是一个底层的 工作单元 2)它本身就是一个完整的搜索引擎 3)应用程序是直接与索引而不是与分片进行交互 4)Elasticsearch 是利用分片将数据分发到集群内各处的 5)分片是数据的容器,文档保存在分片内 6)分片又被分配到集群内的各个节点里 7) 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。 8)一个分片可以是 主分片 或者 副本分片 9)索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量 10)一个副本分片只是一个主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务 11)在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改 其中 status 字段表示当前集群的健康状态(是否正常工作),有三种颜色

Elasticsearch之存储原理

倒排索引被写入磁盘后是不可变的,ES解决不变性和更新索引的方式是使用多个索引,利用新增的索引来反映修改,在查询时从旧的到新的依次查询,最后来一个结果合并。 ES底层是基于Lucene,最核心的概念就是 Segment(段) ,每个段本身就是一个倒排索引。 ES中的Index由多个段的集合和 commit point(提交点) 文件组成。 提交点文件中有一个列表存放着所有已知的段,下面是一个带有1个提交点和3个段的Index示意图: Doc会先被搜集到内存中的Buffer内,这个时候还无法被搜索到,如下图所示: 每隔一段时间,会将buffer提交,在flush磁盘后打开新段使得搜索可见,详细过程如下: 下面展示了这个过程完成后的段和提交点的状态: 通过这种方式,可以使得新文档从被索引到可被搜索间的时间间隔在数分钟,但是还不够快。因为磁盘需要 fsync ,这个就成为性能瓶颈。我们前面提到过Doc会先被从buffer刷入段写入文件系统缓存(很快),那么就自然想到在这个阶段就让文档对搜索可见,随后再被刷入磁盘(较慢)。 Lucene支持对新段写入和打开,可以使文档在没有完全刷入硬盘的状态下就能对搜索可见,而且是一个开销较小的操作,可以频繁进行。 下面是一个已经将Docs刷入段,但还没有完全提交的示意图: 我们可以看到,新段虽然还没有被完全提交,但是已经对搜索可见了。 引入refresh操作的目的是提高ES的实时性,使添加文档尽可能快的被搜索到,同时又避免频繁fsync带来性能开销,依靠的就是文件系统缓存OS cache里缓存的文件可以被打开(open/reopen)和读取,而这个os cache实际是一块内存区域,而非磁盘,所以操作是很快的,这就是ES被称为近实时搜索的原因。 refresh默认执行的间隔是1秒,可以使用 refreshAPI 进行手动操作,但一般不建议这么做。还可以通过合理设置 refresh_interval 在近实时搜索和索引速度间做权衡。 index segment刷入到os cache后就可以打开供查询,这个操作是有潜在风险的,因为os cache中的数据有可能在意外的故障中丢失,而此时数据必备并未刷入到os disk,此时数据丢失将是不可逆的,这个时候就需要一种机制,可以将对es的操作记录下来,来确保当出现故障的时候,已经落地到磁盘的数据不会丢失,并在重启的时候可以从操作记录中将数据恢复过来。elasticsearch提供了translog来记录这些操作,结合os cached segments数据定时落盘来实现数据可靠性保证(flush)。 文档被添加到buffer同时追加到translog: 进行 refresh 操作,清空buffer,文档可被搜索但尚未 flush 到磁盘。translog不会清空: 每隔一段时间(例如translog变得太大),index会被flush到磁盘,新的translog文件被创建,commit执行结束后,会发生以下事件: 下面示意图展示了这个状态: translog记录的是已经 在内存生成(segments)并存储到os cache但是还没写到磁盘的那些索引操作 (注意,有一种解释说,添加到buffer中但是没有被存入segment中的数据没有被记录到translog中,这依赖于写translog的时机,不同版本可能有变化,不影响理解),此时这些新写入的数据可以被搜索到,但是当节点挂掉后这些未来得及落入磁盘的数据就会丢失,可以通过trangslog恢复。 当然translog本身也是磁盘文件,频繁的写入磁盘会带来巨大的IO开销,因此对translog的追加写入操作的同样操作的是os cache,因此也需要定时落盘(fsync)。translog落盘的时间间隔直接决定了ES的可靠性,因为宕机可能导致这个时间间隔内所有的ES操作既没有生成segment磁盘文件,又没有记录到Translog磁盘文件中,导致这期间的所有操作都丢失且无法恢复。 translog的fsync是ES在后台自动执行的,默认是每5秒钟主动进行一次translog fsync,或者当translog文件大小大于512MB主动进行一次fsync,对应的配置是 index.translog.flush_threshold_period 和 index.translog.flush_threshold_size 。 当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点去恢复已知的段,并且会重放 translog 中所有在最后一次提交后发生的变更操作。 translog 也被用来提供实时 CRUD 。当你试着通过ID来RUD一个Doc,它会在从相关的段检索之前先检查 translog 中最新的变更。 默认 translog 是每5秒或是每次请求完成后被 fsync 到磁盘(在主分片和副本分片都会)。也就是说,如果你发起一个index, delete, update, bulk请求写入translog并被fsync到主分片和副本分片的磁盘前不会反回200状态。 这样会带来一些性能损失,可以通过设为异步fsync,但是必须接受由此带来的丢失少量数据的风险: flush 就是执行commit清空、干掉老translog的过程。默认每个分片30分钟或者是translog过于大的时候自动flush一次。可以通过flush API手动触发,但是只会在重启节点或关闭某个索引的时候这样做,因为这可以让未来ES恢复的速度更快(translog文件更小)。 满足下列条件之一就会触发冲刷操作: 整体流程: 删除一个ES文档不会立即从磁盘上移除,它只是被标记成已删除。因为段是不可变的,所以文档既不能从旧的段中移除,旧的段也不能更新以反映文档最新的版本。 ES的做法是,每一个提交点包括一个 .del 文件(还包括新段),包含了段上已经被标记为删除状态的文档。所以,当一个文档被做删除操作,实际上只是在 .del 文件中将该文档标记为删除,依然会在查询时被匹配到,只不过在最终返回结果之前会被从结果中删除。ES将会在用户之后添加更多索引的时候,在后台进行要删除内容的清理。 文档的更新操作和删除是类似的:当一个文档被更新,旧版本的文档被标记为删除,新版本的文档在新的段中索引。 该文档的不同版本都会匹配一个查询,但是较旧的版本会从结果中删除。 通过每秒自动刷新创建新的段,用不了多久段的数量就爆炸了,每个段消费大量文件句柄,内存,cpu资源。更重要的是,每次搜索请求都需要依次检查每个段。段越多,查询越慢。 ES通过后台合并段解决这个问题。ES利用段合并的时机来真正从文件系统删除那些version较老或者是被标记为删除的文档。被删除的文档(或者是version较老的)不会再被合并到新的更大的段中。 可见,段合并主要有两个目的: ES对一个不断有数据写入的索引处理流程如下: 合并过程如图: 从上图可以看到,段合并之前,旧有的Commit和没Commit的小段皆可被搜索。 段合并后的操作: 合并完成后新的段可被搜索,旧的段被删除,如下图所示: 注意 :段合并过程虽然看起来很爽,但是大段的合并可能会占用大量的IO和CPU,如果不加以控制,可能会大大降低搜索性能。段合并的optimize API 不是非常特殊的情况下千万不要使用,默认策略已经足够好了。不恰当的使用可能会将你机器的资源全部耗尽在段合并上,导致无法搜索、无法响应。

分布式搜索引擎elasticsearch的架构原理

分布式搜索引擎:把大量的索引数据拆散成多块,每台机器放一部分,然 后利用多台机器对分散之后的数据进行搜索,所有操作全部是分布在多台机器上进行,形成了 完整的分布式的架构。 近实时,有两层意思: 集群包含多个节点,每个节点属于哪个集群都是通过一个配置来决定的, Node 是集群中的一个节点,节点也有一个名称,默认是随机分配的。默认节点会去加入一个名 称为 elasticsearch 的集群。如果直接启动一堆节点,那么它们会自动组成一个elasticsearch 集群,当然一个节点也可以组成 elasticsearch 集群。 文档是 es 中最小的数据单元,一个 document 可以是1条客户数据、1条商品分类数据、1条 订单数据,通常用json 数据结构来表示。每个 index 下的 type,都可以存储多条 document。 1个 document 里面有多个 field,每个 field 就是1个数据字段。 es 集群多个节点,会自动选举1个节点为 master 节点,这个 master 节点其实就是干一些管理 的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举1个节点为 master 节点。 如果是非 master节点宕机了,那么会由 master 节点,让那个宕机节点上的 primary shard 的身 份转移到其他机器上的 replica shard。接着你要是修复了那个宕机机器,重启了之后,master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。 说得更简单1点,就是说如果某个非 master 节点宕机了,那么此节点上的 primary shard 不就 没了。那好,master 会让 primary shard 对应的 replica shard(在其他机器上)切换为 primary shard。如果宕机的机器修复了,修复后的节点也不再是 primary shard,而是 replica shard。 索引可以拆分成多个 shard ,每个 shard 存储部分数据。拆分多个 shard是有好处的,一是支持横向扩展,比如你数据量是 3T,3 个 shard,每个 shard 就 1T 的数据, 若现在数据量增加到 4T,怎么扩展,很简单,重新建1个有 4 个 shard 的索引,将数据导进 去;二是提高性能,数据分布在多个 shard,即多台服务器上,所有的操作,都会在多台机器 上并行分布式执行,提高了吞吐量和性能。 接着就是这个 shard 的数据实际是有多个备份,就是说每个 shard 都有1个 primary shard ,负责写入数据,但是还有多个 replica shard 。 primary shard 写入数据之后, 会将数据同步到其他几个 replica shard上去。 通过这个 replica 的方案,每个 shard 的数据都有多个备份,如果某个机器宕机了,没关系啊, 还有别的数据副本在别的机器上,这样子就高可用了。 总结:分布式就是两点,1.通过shard切片实现横向扩展;2.通过replica副本机制,实现高可用 基本概念 写数据过程:客户端通过hash选择一个node发送请求,这个node被称做coordinating node(协调节点),协调节点对docmount进行路由,将请求转发给到对应的primary shard,primary shard 处理请求,将数据同步到所有的replica shard,此时协调节点,发现primary shard 和所有的replica shard都处理完之后,就反馈给客户端。 客户端发送get请求到任意一个node节点,然后这个节点就称为协调节点,协调节点对document进行路由,将请求转发到对应的node,此时会使用随机轮询算法,在primary shard 和replica shard中随机选择一个,让读取请求负载均衡,接收请求的node返回document给协调节点,协调节点,返回document给到客户端 es最强大的是做全文检索,就是比如你有三条数据 1.java真好玩儿啊 2.java好难学啊 3.j2ee特别牛 你根据java关键词来搜索,将包含java的document给搜索出来。 更新/删除数据过程,首先还是write、merge操作,然后flush过程中: 1、write过程和上面的一致; 2、refresh过程有点区别 所谓的倒排索引,就是把你的数据内容先分词,每句话分成一个一个的关键词,然后记录好每一个关键词对应出现在了哪些 id 标识的数据。 然后你可以从其他地根据这个 id 找到对应的数据就可以了,这个就是倒排索引的数据格式 以及搜索的方式,这种利倒排索引查找数据的式,也被称之为全文检索。 Inverted Index就是我们常见的倒排索引, 主要包括两部分: 一个有序的数据字典 Dictionary(包括单词 Term 和它出现的频率)。 与单词 Term 对应的 Postings(即存在这个单词的文件) 当我们搜索的时候,首先将搜索的内容分解,然后在字典里找到对应 Term,从而查找到与搜索相关的文件内容。 本质上,Stored Fields 是一个简单的键值对 key-value。默认情况下,Stored Fields是为false的,ElasticSearch 会存储整个文件的 JSON source。 哪些情形下需要显式的指定store属性呢?大多数情况并不是必须的。从_source中获取值是快速而且高效的。如果你的文档长度很长,存储 _source或者从_source中获取field的代价很大,你可以显式的将某些field的store属性设置为yes。缺点如上边所说:假设你存 储了10个field,而如果想获取这10个field的值,则需要多次的io,如果从Stored Field 中获取则只需要一次,而且_source是被压缩过 的。 这个时候你可以指定一些字段store为true,这意味着这个field的数据将会被单独存储(实际上是存两份,source和 Stored Field都存了一份)。这时候,如果你要求返回field1(store:yes),es会分辨出field1已经被存储了,因此不会从_source中加载,而是从field1的存储块中加载。 Doc_values 本质上是一个序列化的 列式存储,这个结构非常适用于聚合(aggregations)、排序(Sorting)、脚本(scripts access to field)等操作。而且,这种存储方式也非常便于压缩,特别是数字类型。这样可以减少磁盘空间并且提高访问速度,ElasticSearch 可以将索引下某一个 Document Value 全部读取到内存中进行操作. Doc_values是存在磁盘的 在es中text类型字段默认只会建立倒排索引,其它几种类型在建立倒排索引的时候还会建立正排索引,当然es是支持自定义的。在这里这个正排索引其实就是Doc Value。 即上文所描述的动态索引 往 es 写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 filesystem cache 中去。 es 的搜索引擎严重依赖于底层的 filesystem cache ,你如果给 filesystem cache 更多的 内存,尽量让内存可以容纳所有的 idx segment file 索引数据文件,那么你搜索的时候就 基本都是走内存的,性能会非常高。 性能差距究竟可以有多大?我们之前很多的测试和压测,如果走磁盘一般肯定上秒,搜索性能 绝对是秒级别的,1秒、5秒、10秒。但如果是走 filesystem cache ,是走纯内存的,那么一 般来说性能比走磁盘要高一个数量级,基本上就是毫秒级的,从几毫秒到几百毫秒不等。 那如何才能节约filesystem cache这部分的空间呢? 当写数据到ES时就要考虑到最小化数据,当一行数据有30几个字段,并不需要把所有的数据都写入到ES,只需要把关键的需要检索的几列写入。这样能够缓存的数据就会越多。 所以需要控制每台机器写入的数据最好小于等于或者略大于filesystem cache空间最好。 如果要搜索海量数据,可以考虑用ES+Hbase架构。用Hbase存储海量数据,然后ES搜索出doc id后,再去Hbase中根据doc id查询指定的行数据。 当每台机器写入的数据大于cache os太多时,导致太多的数据无法放入缓存,那么就可以把一部分热点数据刷入缓存中。 对于那些你觉得比较热的、经常会有人访问的数据,最好做个专门的缓存预热系统,就是 对热数据每隔一段时间,就提前访问一下,让数据进入 filesystem cache 里去。这样下 次别人访问的时候,性能肯定会好很多。 把热数据和冷数据分开,写入不同的索引里,然后确保把热索引数据刷到cache里。 在ES里最好不要用复杂的关联表的操作。当需要这样的场景时,可以在创建索引的时候,就把数据关联好。比如在mysql中需要根据关联ID查询两张表的关联数据:select A.name ,B.age from A join B where A.id = B.id,在写入ES时直接去把相关联数据放到一个document就好。 es 的分页是较坑的,为啥呢?举个例子吧,假如你每页是 10 条数据,你现在要查询第 100 页,实际上是会把每个 shard 上存储的前 1000 条数据都查到1个协调节点上,如果你有个 5 个 shard,那么就有 5000 条数据,接着协调节点对这 5000 条数据进行一些合并、处理,再获取到 最终第 100 页的 10 条数据。 分布式的,你要查第 100 页的 10 条数据,不可能说从 5 个 shard,每个 shard 就查 2 条数据, 最后到协调节点合并成 10 条数据吧?你必须得从每个 shard 都查 1000 条数据过来,然后根据 你的需求进行排序、筛选等等操作,最后再次分页,拿到里面第 100 页的数据。你翻页的时 候,翻的越深,每个 shard 返回的数据就越多,而且协调节点处理的时间越长,非常坑爹。所 以用 es 做分页的时候,你会发现越翻到后面,就越是慢。 我们之前也是遇到过这个问题,用 es 作分页,前几页就几十毫秒,翻到 10 页或者几十页的时 候,基本上就要 5~10 秒才能查出来一页数据了。 解决方案吗? 1)不允许深度分页:跟产品经理说,你系统不允许翻那么深的页,默认翻的越深,性能就越差; 2)在APP或者公众号里,通过下拉来实现分页,即下拉时获取到最新页,可以通过scroll api来实现; scroll 会1次性给你生成所有数据的1个快照,然后每次滑动向后翻页就是通过游标 scroll_id 移动获取下一页,性能会比上面说的那种分页性能要高很多很 多,基本上都是毫秒级的。 但是,唯1的缺点就是,这个适合于那种类似微博下拉翻页的,不能随意跳到任何一页的场 景。也就是说,你不能先进到第 10 页,然后去第 120 页,然后再回到第 58 页,不能随意乱跳 页。所以现在很多APP产品,都是不允许你随意翻页的,也有一些网站,做的就是你只能往 下拉,一页一页的翻。 初始化时必须指定 scroll 参数,告诉 es 要保存此次搜索的上下文多长时间。你需要确保用户不会持续不断翻页翻几个小时,否则可能因为超时而失败。 除了用 scroll api ,也可以用 search_after 来做, search_after 的思想是使用前一页的结果来帮助检索下一页的数据,显然,这种方式也不允许你随意翻页,你只能一页一页往后 翻。初始化时,需要使用一个唯1值的字段作为 sort 字段。

为什么我的tage插件和ccseting插件冲突

安装插件前需要注意的事项: 1、可兼容的插件独立安装测试有效,但并不排除插件之间存在冲突的可能性; 2、由于测试设备有限,并不排除部分插件并不兼容某些iOS设备; 3、安装插件存在风险,为以防万一,请务必做好重要资料备份工作。 B

SCServer.exe的SCServer.exe详细信息:

SCServer是Search Client Server的缩写,SCServer.exe是Microsoft Search Client Server的组件之一,是随着Microsoft KB982217更新程序的安装加入到操作系统的,该更新程序通过更新后,会在Windows任务管理器进程窗口中出现两个多余的进程,即SCServer.exe和Seaport.exe。这两个进程包含在KB982217更新程序安装包中,安装更新程序后可在安装目录C:Program FilesMicrosoftSearch Enhancement Pack中找到它们的程序文件。附:KB982217更新程序包共包括以下文件: 文件名称 版本 日期 大小(单位:kb) aab.xap 2010-5-14 33.7 aabloc.xap 2010-5-14 71.2 ARPManager.exe 3.0.126.0 2010-5-14 58.3 overlay.js 2010-5-14 65.5 SCServer.exe 3.0.126.0 2010-5-14 308 SeaNote.cab 2010-5-14 7.83 SeaNote.dll 3.0.126.0 2010-5-14 240 SeaPort.cab 2010-5-14 7.64 SeaPort.exe 3.0.126.0 2010-5-14 243 SearchBoxExt.cab 2010-5-14 47.3 SearchEnhancementPack.cab 2010-5-14 746 SearchEnhancementPack.msi 2010-5-14 849 SearchEnhancementPackSetup.exe 7.0.6436.1 2010-5-14 808 SearchOptionsFlyout.xap 2010-5-14 21.5 四舍五入 SearchOptionsFlyoutLoc.xap 2010-5-14 83.5 SEPSearchHelperff.dll 3.0.126.0 2010-5-14 226 SEPSearchHelperie.dll 3.0.126.0 2010-5-14 187 setup.exe 3.0.126.0 2010-5-14 86.7 SHelper.cab 2010-5-14 7.07 SrchBxEx.dll 3.0.126.0 2010-5-14 179

安装proe wildfire5.0时打开setup.exe后出现welcome to PTC后进度条走一半就出现ptcsetup.exe已停止工作?

没破解好!!!

nutch和elasticsearch的区别

网络爬虫架构在Nutch+Hadoop之上,是一个典型的分布式离线批量处理架构,有非常优异的吞吐量和抓取性能并提供了大量的配置定制选项。由于网络爬虫只负责网络资源的抓取,所以,需要一个分布式搜索引擎,用来对网络爬虫抓取到的网络资源进行实时的索引和搜索。搜 索引擎架构在ElasticSearch之上,是一个典型的分布式在线实时交互查询架构,无单点故障,高伸缩、高可用。对大量信息的索引与搜索都可以在近 乎实时的情况下完成,能够快速实时搜索数十亿的文件以及PB级的数据,同时提供了全方面的选项,可以对该引擎的几乎每个方面进行定制。支持RESTful 的API,可以使用JSON通过HTTP调用它的各种功能,包括搜索、分析与监控。此外,还为Java、PHP、Perl、Python以及Ruby等各 种语言提供了原生的客户端类库。网络爬虫通过将抓取到的数据进行结构化提取之后提交给搜索引擎进行索引,以供查询分析使用。由于搜索引擎的设计目标在于近乎实时的复杂的交互式查询,所以搜索引擎并不保存索引网页的原始内容,因此,需要一个近乎实时的分布式数据库来存储网页的原始内容。分布式数据库架构在Hbase+Hadoop之上,是一个典型的分布式在线实时随机读写架构。极强的水平伸缩性,支持数十亿的行和数百万的列,能够对网络爬虫提交的数据进行实时写入,并能配合搜索引擎,根据搜索结果实时获取数据。网 络爬虫、分布式数据库、搜索引擎均运行在普通商业硬件构成的集群上。集群采用分布式架构,能扩展到成千上万台机器,具有容错机制,部分机器节点发生故障不 会造成数据丢失也不会导致计算任务失败。不但高可用,当节点发生故障时能迅速进行故障转移,而且高伸缩,只需要简单地增加机器就能水平线性伸缩、提升数据 存储容量和计算速度。网络爬虫、分布式数据库、搜索引擎之间的关系:1、网络爬虫将抓取到的HTML页面解析完成之后,把解析出的数据加入缓冲区队列,由其他两个线程负责处理数据,一个线程负责将数据保存到分布式数据库,一个线程负责将数据提交到搜索引擎进行索引。2、搜索引擎处理用户的搜索条件,并将搜索结果返回给用户,如果用户查看网页快照,则从分布式数据库中获取网页的原始内容。整体架构如下图所示:爬虫集群、分布式数据库集群、搜索引擎集群在物理部署上,可以部署到同一个硬件集群上,也可以分开部署,形成1-3个硬件集群。网络爬虫集群有一个专门的网络爬虫配置管理系统来负责爬虫的配置和管理,如下图所示:搜 索引擎通过分片(shard)和副本(replica)实现了高性能、高伸缩和高可用。分片技术为大规模并行索引和搜索提供了支持,极大地提高了索引和搜 索的性能,极大地提高了水平扩展能力;副本技术为数据提供冗余,部分机器故障不影响系统的正常使用,保证了系统的持续高可用。有2个分片和3份副本的索引结构如下所示:一个完整的索引被切分为0和1两个独立部分,每一部分都有2个副本,即下面的灰色部分。在 生产环境中,随着数据规模的增大,只需简单地增加硬件机器节点即可,搜索引擎会自动地调整分片数以适应硬件的增加,当部分节点退役的时候,搜索引擎也会自 动调整分片数以适应硬件的减少,同时可以根据硬件的可靠性水平及存储容量的变化随时更改副本数,这一切都是动态的,不需要重启集群,这也是高可用的重要保 障。

请问计算机考试中的CCNA CCNP CCIE MCP MCSA MCSE MCSD SCJP ORACLE CIW都各是什么意思???

CCNA:思科认证网络支持工程师CCNP全称是:Cisco Certified Network Professional——思科认证网络高级工程师 CCIE全称Cisco Certified Internetwork Expert,是美国Cisco公司于1993年开始推出的专家级认证考试。微软认证专家 (MCP = Microsoft Certified Professional) MCSA是微软认证系统管理员的简称,微软认证系统工程师(MCSE)MCSD(Microsoft Certified Solution Developer)微软认证解决方案开发专家。sun certificated java programmer (SCJP) 一种Java认证考试 对于Java程序设计员,Sun推出两项认证:Sun Certificated Java Programmer (SCJP)和Sun Certificated Java Developer(SCJD)。Oracle是世界领先的信息管理软件开发商,因其复杂的关系数据库产品而闻名。CIW(Certified Internet Webmaster),是世界上最具权威地位的超越厂商背景的互联网证书。

www.scse.com.cn|广州大学华软软件学院官方网站

网站:广州大学华软软件学院 网站地址:www.scse.com.cn 广州大学华软软件学院网站地址:http://www.scse.com.cn

考下深信服SCSE证书,有什么用?

头号安全公司的认证考下了好处让人仰视啊,具备安全专家水平,职业方向更广阔,网络安全专家岗位,课程内容里渗透测试和应急响应知识,熟悉渗透测试流程,具备应急响应能力。了解全面防御新型攻击的手段,了解与网络安全相关的法律法规,能过针对企业网络进行合规性评估,了解业界通用的安全框架及安全理念,熟悉等级保护建设流程,掌握等级保护建设思路,能够根据需求对企业网络进行等保合规改造,具备网络风险发现能力,并根据发现的风险进行安全加固,提升企业网络抗风险能力,熟悉安全运营流程,根据企业需要制定自动化运营方案,掌握云安全相关知识,能够对企业上云的业务提供可靠的安全解决方案。去谷安学院的官网上详细的了解看看吧,别走冤枉路

路虎scse是什么意思?

sc是机械增压,se是低配。hse是高配。希望对你有用。【汽车问题,问汽车大师。4S店专业技师,10分钟解决。】

scse是什么专业

scse是计算机科学专业。计算机科学通过软件算法和数据结构、设计方法和语言范式的设计,关注计算机技术的有效应用。该计划强调高效可靠的软件的实用设计,以满足规范。计算机科学与计算机工程有一些共同的主题,包括计算机网络、信息存储和管理。这两个学科共享基本原则,因为每个学科都认识到现有技术和应用程序所施加的限制。不同之处在于算法和概念层面的重点。计算机科学更侧重于软件设计和构建,不包括电路、基础电子学或数字通信等学科。这门计算机科学课程与科学学位之间的主要区别在于侧重于计算机科学基础的面向实践的应用。

ElasticSearch搜索term和terms的区别

http://www.cnblogs.com/zhaijunming5/p/6427100.html

如何打开elasticsearch

[hadoop@fat283-0003 ~]$ curl -XGET localhost:9200{"status" : 200,"name" : "She-Venom","cluster_name" : "elasticsearch","version" : {"number" : "1.7.2","build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec","build_timestamp" : "2015-09-14T09:49:53Z","build_snapshot" : false,"lucene_version" : "4.10.4"},"tagline" : "You Know, for Search"}

pessimisticselfcrossing是什么意思?

—— 英文: pessimistic self crossing 悲观的自我穿越( 悲观主义者 )。

sgccseccsphcspcc代号的意思是什么, 有何区别?

这四个都是钢材的牌号 SGCC 热浸镀锌薄钢板 S- Steel钢 G- 镀锌Galvanized C- Cold冷轧 第四位 C- Common普通级 SECC 电解亚铅镀锌 S-钢(Steel)、E-电镀(Electrodeposition)、C-冷轧(Cold)、第四位C-普通级 SPHC 一般用热轧钢板及钢带 S-钢 P板 H热扎 C一般商业 SPCC 一般用冷轧钢板及钢带 S-钢 P板 C冷轧 C一般商业~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SPHC这个牌号其实最早是德国的牌号,日本也用,后来国内钢厂宝钢引入,代表的是的热轧钢板(它对应的冷轧板就是SPCC),相当于国标GB699(优质碳素结构钢国家标准)中的10#、15#钢的热轧板,他们的含碳量范围是0.1-0.15%左右。

sgccseccsphcspcc代号的意思是什么, 有何区别?

这四个都是钢材的牌号 SGCC 热浸镀锌薄钢板 S- Steel钢 G- 镀锌Galvanized C- Cold冷轧 第四位 C- Common普通级 SECC 电解亚铅镀锌 S-钢(Steel)、E-电镀(Electrodeposition)、C-冷轧(Cold)、第四位C-普通级 SPHC 一般用热轧钢板及钢带 S-钢 P板 H热扎 C一般商业 SPCC 一般用冷轧钢板及钢带 S-钢 P板 C冷轧 C一般商业~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SPHC这个牌号其实最早是德国的牌号,日本也用,后来国内钢厂宝钢引入,代表的是的热轧钢板(它对应的冷轧板就是SPCC),相当于国标GB699(优质碳素结构钢国家标准)中的10#、15#钢的热轧板,他们的含碳量范围是0.1-0.15%左右。

igcse的esl的b大概是什么难度?用雅思来算的话?

6分左右吧

Elasticsearch 设置账号密码

前言 7.0以后es把基础的安全模块免费集成了。很棒。现在试试设置吧。 官网安全模块文档 其中包含了一个安全入门教程 正文 下面基本都是以我的操作为例,实际上可以按照官网文档进行其它的尝试。 一、设置账号密码 单节点 在elasticsearch.yml文件里增加配置 初始化密码需要在es启动的情况下进行设置,按照提示输入各个内置用户的密码。

如何重装vncserver服务

linux开机自动启动vncserver服务,需要先保证VNC安装无问题以及各种配置以及防火墙正常,下面是vncserver服务安装、配置以及设置自启动的步骤:首先需要检查一下服务器是否已经安装了VNC服务,检查服务器的是否安装VNC的命令如下:rpm -qa grep vnc使用了上面的命令我这边返回的信息是下面的(如果没有任何显示,则说明系统没有安装vnc包)tigervnc-1.1.0-5.el6.i686tigervnc-server-1.1.0-5.el6.i686如果没有安装vnc可以使用下面命令进行安装:yum install tigervnc tigervnc-server接下来就是安装之后的配置问题了。使用下面的命令编辑配置文件:vi /etc/sysconfig/vncservers使用上面命令的时候,可能您服务器上面已经存在这个配置文件,也可能您服务器上面不存在这个配置文件,将下面的内容添加到配置文件内:VNCSERVERS="1:root"VNCSERVERARGS[1]="-geometry 800x600"下面这段是上面所讲配置文件注解,做参考之用:#这个是配置远程桌面登录的用户名,如果两个用户,则使用VNCSERVERS="1:user1 2:user2" ,,依次类推,默认情况下,1:user1对应5901,2:user2对应5902(VNC的默认监听端口是5900,监听端口规则为590+usernumber),如下VNCSERVERS="usernumber:myusername" #下面这项配置为登录桌面配置,其中的“1”为用户序号,800x600为分辨率,-nolisten tcp为阻止tcp包,-localhost代表只监听本地,VNCSERVERARGS[1]="-geometry 800x600 -nolisten tcp -localhost"如果想阻止http包,可以使用如下配置VNCSERVERARGS[1]="-geometry 800x600 -nolisten tcp -nohttpd -localhost"使用下面的命令为vnc设置密码(需要使用su 切换到要设置vnc密码的用户上,比如:su user1,其中user1就是在上面配置文件内写的帐号)vncpasswd设置好密码之后,就是启动VNC服务了,启动VNC服务的时候也需要用su user1(user1就是在上面配置文件内写的帐号)切换到要启动服务的帐号上(很多朋友在使用DirectSpace默认的桌面VNC的时候,遇到无法连接“10061错误”,即可在ssh下输入下面命令解决!)vncserver其他命令,比如重启VNC服务就用下面的命令:service vncserver restart设置VNC服务开机启动用下面的命令:chkconfig vncserver on在一些minimal系统里,即使英文也会出现方框乱码,请使用本处命令修正:yum -y install fontforge其它说明:设置完毕后使用servers vncserver start(如果不能启动,检查软件是否安装正常,检查/etc/rc.d/init.d目录是否存在vncserver控制脚本),启动完毕后使用netstat -nat查看监听端口(默认为5901,5902,5903等),如果开启了防火墙,则需要配置规则允许对应端口tcp包通过。参考配置:iptables -I INPUT 1 -p tcp --dport 5901 -j ACCEPT(其中-I INPUT 1代表插入一条规则,这条规则的位置是1,详情请查阅iptables相关配置)

centos7 linux vnc永久开启的方法是什么?每次重启都有vncserver好麻烦

chkconfig vncserver on

c盘下面有arcldr.exe arcsetup.exe ntldr 为几个文件是做什么用的?

如果你从微软和网络上搜索,你可以找到解释就是“同Ntldr、Ntdetect.com四个文件一起用于启动不同计算机的” 原文“...Ntldr, Ntdetect.com, Arcsetup.exe, and Arcldr.exe files that are used for booting various computers...” 你如果不知道ARC,你一定搞不清楚说的什么意思。 要了解这两个文件,你需要先知道ARC,ARC是x86或RISC计算机中用于标识设备的动态方法。 ARC命名的第一部分用于标识硬件适配卡/磁盘控制器,它有两个选项:SCSI和Multi。Multi表示一个非SCSI硬盘或一个由SCSI BIOS访问的SCSI硬盘,而SCSI则表示一个SCSI BIOS禁止的SCSI硬盘;(x)是硬件适配卡序号;disk(x)表示SCSI总线号,即如果硬件适配卡为Multi,其正确表示方法就为disk(0);rdisk(x)表示硬盘的序号,即如果硬件适配卡为SCSI则忽略此值;partition(x)表示硬盘的分区序号。

微软的 MCSE 认证,含金量怎么样,对于以后的面试系统工程师有多大帮助。。。。。。培训费用是多少?

这个看你自己想往哪方面发展啊?要是想往网络技术方面发展话有认证肯定是比较容易获的认可的,介意你找家专业的培训机构好好了解下,江苏万和计算机培训中心好像挺不错的,可以去问问,毕竟比较专业的机构会给你比较合理的建议嘛。

ccna和mcse那个证好考一些

楼主您好,ccna容易一些,您可以去鸿鹄论坛看看,思科考生聚集的地方

MCSE现在还有用吗,工资能拿多少,和CCNP比较,哪个含金量高呢

目前是经济衰退的时期,找一份工作不容易,考取MCSE的证书当然是有用的,能够帮助你稳定你的位置,增加求职的法码。如果考试的话,建议去itrenzheng考题网去看看学习资料,对你很有帮助的。

MCSE认证的考试费和报名费分别是多少,那些机构是属于授权的教学机构。

你可以在Pearson VUE 考试中心报名参加考试的,微软的每一门考试科目都是50美金。MCSE2003 需要考试 7 门考试,这 7 门考试的考试组合丰富多样,常见的一种组合式: 70-270/70-620 290 291 293 294 298 431 ,其中 70-290 291 293 294 是必考科目MCSE2008 需要考试 5 门,其考试科目相对比较固定 70-620 640 642 643 647 ,每门考试获得一个证书,一张总的 MCTS 证书和一张总的 MCITP 证书,一张 WINDOWS SERVER 2008 总证。

MCSE2008的考试的科目

MCSE2008需要考试7门考试,这7门考试的考试组合丰富多样,常见的一种组合式:70-270 290 291 293 294 298 431,其中70-290 291 293 294是必考科目MCSE2008需要考试5门,其考试科目相对比较固定70-620 640 642 643 647,每考完一门考试会获得一张MCTS的证书,完成第一门考试会获得2涨MCTS,一张是欢迎的MCTS,一张是考试课程的MCTS,全部考完可以拿到7张证书,5张MCTS,一张MCSA,一张MCITP证书! 所以,我们建议,目前从事的主要还是WINDOWS SERVER 2003技术的,最好选择MCSE2003,没有特别要求的,最好选择MCSE2008。因为MCSE2003终归会退出历史舞台。

MCSE 2012认证有哪些种类?如何获得MCSE 2012认证?大神们帮帮忙

总的来说,MCSE 2012认证还是蛮复杂的,种类繁多,下面我来详细介绍给您,希望可以帮到您! (一)MCSE 2012服务器基础构架(Server Infrastructure) 1:MCSE 2012服务器基础构架考试科目:70-410 411 412 413 414 2:升级到MCSE 2012服务器基础构架: 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 413 414三科考试即可获得MCSE 2012 Server Infrastructure MCSA: Windows Server 2008 MCITP: Server Administrator on Windows Server 2008 MCITP: Enterprise Administrator on Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 MCITP: Enterprise Desktop Administrator on Windows 7 (二)MCSE 2012桌面基础构架(Desktop Infrastructure) 1:MCSE 2012桌面基础构架考试科目:70-410 411 412 415 416 2:升级到MCSE 2012桌面基础构架: 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 415 416三科考试即可获得MCSE 2012 Desktop Infrastructure MCITP: Enterprise Desktop Administrator on Windows 7 MCSA: Windows Server 2008 MCITP: Server Administrator on Windows Server 2008 MCITP: Enterprise Administrator on Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 (三)MCSE私有云认证(Private Cloud ) 1:MCSE 2012私有云认证考试科目:70-410 411 412 246 247 2:MCSE 2008私有云认证考试科目:70-640 642 646 246 247 3:升级到MCSE 2012私有云认证: 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 246 247三科考试即可获得MCSE 2012 Private Cloud MCSA: Windows Server 2008 MCITP: Server Administrator on Windows Server 2008 MCITP: Enterprise Administrator on Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 MCITP: Enterprise Desktop Administrator on Windows 7 (四)MCSE 2012 SQL Server 1:MCSE 2012数据平台认证(Data Platform) MCSE 2012数据平台认证考试科目:70-461 462 463 464 465 升级到MCSE 2012数据平台认证:已经获得MCITP:Database Developer 2008或Database Administrator 2008,加考70-457 458 459即可。 2:MCSE 2012商务智能认证(Business Intelligence) MCSE 2012商务智能认证考试科目:70-461 462 463 466 467 升级到MCSE 2012商务智能认证:已经获得MCITP:Business Intelligence,加考70-457 458 460即可获得 (五)MCSE 2012 Messaging 1:MCSE Messaging 2012考试科目:70-410 411 412 341 342 2:升级到MCSE Messaging 2012途径: 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 341 342三科考试即可获得MCSE 2012 Messaging MCSA: Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator on Exchange 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 MCITP: Enterprise Desktop Administrator on Windows 7 (六)代考MCSE 2012 Communication 1:MCSE Communication 2012认证考试科目:70-410 411 412 336 337 2:升级到MCSE Communication 2012认证 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 336 337三科考试即可获得MCSE 2012 Communication MCSA: Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 MCITP: Enterprise Desktop Administrator on Windows 7 (七)MCSE 2012 Sharepoint认证 1:MCSE Sharepoint 2012认证考试科目:70-410 411 412 331 332 2:升级到MCSE Sharepoint 2012认证 如果您已经获得以下认证的任何一种,只需要通过升级考试70-417 331 332三科考试即可获得MCSE Sharepoint 2012 MCSA: Windows Server 2008 MCITP: Virtualization Administrator on Windows Server 2008 R2 MCITP: Enterprise Messaging Administrator 2010 MCITP: Lync Server Administrator 2010 MCITP: SharePoint Administrator 2010 MCITP: Enterprise Desktop Administrator on Windows 7 更多关于MCSE 2012认证相关信息可以到 www.mcseccna.com 了解。

MCSE 和 MCITP 这两个认证哪个好?

本人认为MCITP好点,MSCE在中国很普遍,考一个这样的证很容易,交点钱就拿下来了

聊聊elasticsearch7.8的模板和动态映射

最近想写一篇es的索引的一个设计,由于设计的东西特别多,当然,elasticsearch的模板和动态映射也是其中的一个设计点,所以干脆先来聊聊索引的模板和动态映射,模板,听这个名字就相当于一些公共可用的东西可以作为所有索引的一个设置, 1.1、elasticsearch模板介绍 这里说明下,elasticsearch7.8的模板接口发生了一些变化,_template接口将在后期被废弃(虽然还能使用,不推荐),所以本文不介绍这个接口。既然有废弃的那肯定有新的方式来玩模板了。 最详细接介绍看官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/index-templates.html 现在模板分为两种模板,一个索引模板(index templates ),一个是组件模板(component templates),索引模板是告诉Elasticsearch如何在创建索引时配置索引的一种方法。模板是在创建索引之前配置的,当手动或通过索引文档创建索引时,模板的基础设置将用作创建索引。组件模板是可重用的构建块,用于配置映射、设置和别名。使用组件模板来构造索引模板,组件模板不能直接应用于索引。索引模板可以包含组件模板的集合,也可以直接指定设置、映射和别名。组件模板的接口是: _component_template ,而索引模板的接口是: _index_template ,下面来个官方的例子,可以明显的看出来组件模板component_template1和other_component_template被索引模板通过参数composed_of被引用,所以索引模板template_1既包括自己的设置,又包括了两个组件模板的设置,这样就可以轻松灵活的做组合,降低耦合性。 通过上面的接收,应该就清楚了这两个模板之间的关系,可以用来干嘛了。接下来一一介绍下这两个模板。 1.2、Component templates(组件模板) 先上官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/indices-templates-v1.html 组件模板是构建索引模板的构建块。比如指定索引映射、设置和别名等。 使用语法: 索引模板可以由多个组件模板组成。要使用组件模板,请在索引模板通过参数composed_of指定。组件模板仅作为匹配索引模板的一部分。在任何的索引或者索引模板中定义的一些内容(设置,mapping等)都会覆盖组件模板中与之相同的内容,也就是说组件模板等级最低了,容易被取代。组件模板的只会在索引创建的时候生效,修改组件模板不会对现有的索引有影响。下面介绍下组件模板请求体的一些参数: 举个例子,一看就懂: 1.3、index templates(索引模板) 先看官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/indices-put-template.html 使用语法: 索引模板定义可以定义设置、映射和别名等,然后通过匹配自动应用于新建的索引。Elasticsearch基于与索引名称匹配的通配符模式将模板应用于新索引,也就是说通过索引进行匹配,看看新建的索引是否符合索引模板,如果符合,就将索引模板的相关设置应用到新的索引,如果同时符合多个索引模板呢,这里需要对参数priority进行比较,这样会选择priority大的那个模板进行创建索引。在创建索引模板时,如果匹配有包含的关系,或者相同,则必须设置priority为不同的值,否则会报错。索引模板也是只有在新创建的时候起到作用,修改索引模板对现有的索引没有影响。同样如果在索引中设置了一些设置或者mapping都会覆盖索引模板中相同的设置或者mapping。接下来看看创建索引模板请求体的一些参数: 看这些,好像很复杂,举个例子就容易了:(匹配所有te开头的新建索引,分片为1,优先级为10) 这里没有说组合索引的使用,请看第一节介绍部分,这两种索引的关系,还有就是组合索引被引用顺序,后者更具有更高的优先级,会覆盖前面的一些组合索引的一些相同的设置,然而组件索引不同的部分将会叠加在一起成为索引模板的设置。语法确实不难,但是怎么应用好呢,比如在elk中使用索引模板写数据到es,比如索引设计,怎么把索引自动滚动呢,这块后期会有文章介绍,尽请期待。当然还有动态模板没有介绍,继续往下走。 注意:其实个人觉得把动态模板写这里是为了区分索引模板和动态模板,因为个人混淆过,所以写这里比较好区别,其实动态模板不是索引模板,这里不要误会,其实动态模板就是可以配置在索引中或者配置在索引模板中,作用是elasticsearch对数据探索自发现添加,可以指定匹配,并映射成指定类型。这里要记住elasticsearch只有组合模板和索引模板,动态模板时动态映射的一种实现。动态模板定义了索引创建后新添加字段的映射规则,而索引模板是在创建索引时默认为索引添加的别名、配置和映射等信息。索引模板包含该模板适用索引的模式或规则,以及索引创建时默认包含的别名、配置和映射关系等。它们分别通过index_patterns、aliases、settings和mappings等四个参数设置 在说动态模板之前,先要说说动态映射。 Elasticsearch最重要的功能之一就是可以自动探索数据。要为文档编制索引,不必首先创建索引、定义映射类型和定义字段,只需为文档编制索引,索引、类型和字段就会自动生成。 自动检测和添加新字段以及字段类型称为动态映射,主要分为动态字段和动态模板。这里引出动态字段和动态模板,所以先看看动态字段。 2.1、Dynamic field mapping(动态字段映射) 先看官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/dynamic-field-mapping.html 默认情况下,当在文档中找到索引没有定义的字段时,Elasticsearch会将新字段添加到类型映射中。通过将参数dynamic设置为false(忽略新字段)或strict(遇到未知字段时引发异常),可以在文档和对象级别禁用此行为。 假设启用了动态字段映射,则使用一些简单规则来确定字段应具有的数据类型:当然不是所有的类型都可以自动映射的,只有field data types这些可以动态的探索映射,所以其他的数据类型需要显示的指定。例如: 说起来可能比较有点不好理解,那就需要例子说明了: 这样就自动把create_date在映射中添加了,并且字段类型为date,这就是动态字段映射,也就是elasticsearch的一个特色,这样就不要给所有的字段提前定义好,但是虽然方便了,但是不利于索引的管理,如果出现了一条异常的数据插入到索引中,这样就会导致索引中的mapping中出现很多不必要的字段,动态字段映射可以更具需求对其进行配置。 2.2、Dynamic templates(动态模板) 详情见官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/dynamic-templates.html 动态模板(Dynamic Template)用于自定义动态添加字段时的映射规则,可通过索引映射类型的dynamic_templates参数设置。该参数接收一组命名的动态模板,每一个模板由匹配条件和映射规则组成。匹配条件定义了新字段是否可以使用当前模板,可根据新字段的数据类型、名称和路径来定义条件;而映射规则由参数mapping定义,它需要给出新字段要使用哪些参数,可使用type定义新字段数据类型。 使用规则如下: 使用语法: 这里只举例说明一个规则或者说是条件:match_mapping_type 查看结果 其实静下心来看也不难,其他的规则可以看官网的例子。

「必备技能」Elasticsearch索引全生命周期管理(附代码)

索引(Index)是Elasticsearch中最重要的概念之一,也是整个Elasticsearch操作的基础,Elasticsearch提供了Index APIs用于Elasticsearch生命周期的管理,包括索引的创建、查询、删除和设置,索引的冻结和解冻、拆分和收缩等,掌握索引的管理是Elasticsearch开发、运维的基础能力,也有助于后期对于Elasticsearch的优化。 创建一个索引可以使用Elasticsearch提供的API,其格式如下: 其中 为要创建的索引的名称,是一个必须的参数,所有的字母都必须是小写形式。在创建索引的同时还可以进行相关的设置: 一个不做任何设置的,单纯创建索引的请求如下: 响应体中 “acknowledged” 为true代表索引已经成功在Elasticsearch集群中创建, “shards_acknowledged” 为true则代表在请求超时之前所有的索引分片的副本分片也全部准备完毕。当然,即使 “acknowledged” 和 "shards_acknowledged" 都为false,只能代表超时之前没有完成,后续集群还是可能最终成功创建了索引。 创建索引的API还支持Query Parameters和Request Body,其中的参数均是 可选的参数 。 Query Parameters支持以下参数: Request Body也支持三个参数: 以下代码示例同时指定了Query Parameters和Request Body : 通过Get index API,可以查询一个或者多个索引的相关信息,其API格式如下: 其中target可以是数据流、索引,还可以是一个别名,多个索引之间使用逗号分隔,target还支持模糊查询(*),如果查询所有的索引,可以使用 * 或者 _all 。如果集群开启了安全权限控制,那么要查询索引信息需要获得 view_index_metadata 或者 manage 的索引操作权限。以下为查询的具体案例: Get index API支持带url查询参数,这些参数都是可选参数,主要有以下几个: 首先需要明确索引本身是不能被修改的,当我们说修改索引时,实际上是指修改索引的别名、字段映射(mapping)和配置(settings)。 首先说明一下别名的作用。Elasticsearch提供了别名的功能,一个别名可以添加多个索引,方便通过操作一个别名实际上操作到多个具体的索引,例如每年建一个索引,分别有index-2019,index-2020,index-2021,index-2022共4个索引,这4个索引都关联了别名index-year,当需要查询最近4年的数据的时候,可以使用index-year同时查询这4个年份的索引。 别名的修改,实际上是从索引上删除别名,再重新添加新的别名,将这两个动作放在一起,保证其原子性,确保不会存在别名被删除的瞬间产生没有指向任何索引的问题。 以下代码为将my-index从索引my-index-000001解除,然后重新绑定在索引my-index-000002上。 mapping指定了索引的数据结构,字段类型,修改索引的mapping,可以修改原有字段的名称、类型,添加新的字段等。以下为添加新的email字段,类型为keyword。 支持多个索引、data stream和别名,支持模糊搜索,使用 * 或者 _all 可以指定所有的data stream和别名。 以下为修改settings的案例,设置索引有2个主分片,2个副本。 删除索引将会删除其对应的文档、分片和集群中的元数据信息,索引的操作是一个高危操作,需要慎重,如果集群开启了安全权限控制,那么要删除索引,需要获得 delete_index 或者 manage 的索引操作权限。 不能删除数据流(data stream)的写索引,要删除当前写索引,必须对data stream进行rollover,创建新的写索引。 删除索引的API如下: 是必须参数,指定索引名称,多个索引可以用逗号分割,不支持使用别名,默认情况下也不支持使用模糊匹配,确实需要使用模糊匹配的,需要将集群参数 action.destructive_requires_name 设置为false。 Delete Index API类似Get Index API,同样支持URL查询参数,这些参数包括 allow_no_indices 、 expand_wildcards 、 ignore_unavailable 、 master_timeout 、 timeout ,含义类似,不再赘述。 以下是删除索引的案例代码: 默认情况下,索引一旦被创建出来就是打开的状态,但是在某些情况下可能需要关闭索引,例如一些老旧不需要使用到的索引,仍然占用一定的空间,并且集群仍然需要一定的维护开销,关闭索引将阻塞所有对这个索引的读/写操作,关闭的索引不必维护索引或搜索文档的内部数据结构,从而可以减少集群上开销。 特别注意:关闭索引的操作会消耗大量磁盘空间,在生产上也是一个需要特别注意的操作。可以通过集群设置API将 cluster.indices.close.enable 设置为false来禁用索引的关闭,默认为true。 当一个索引被打开或者关闭,master节点负责重启分片,这些分片都会经历recovery过程,打开或者关闭索引后都会自动进行分片数据的复制,以保证有足够的副本分片以保证高可用性。 默认情况下只支持匹配全名称的特定的索引,但是如果设置了参数 action.destructive_requires_name 为false,则可以使用*或者_all指代所有的索引,但这种情况下一旦有一个索引匹配失败则会报错,不建议开启。 open API用于重新打开被关闭的索引,如果目标是一个data stream,则打开这个data stream背后对应的所有的索引。 默认情况下只支持匹配全名称的特定的索引,但是如果设置了参数 action.destructive_requires_name 为false,则可以使用 * 或者 _all 指代所有的索引,但这种情况下一旦有一个索引匹配失败则会报错。 索引收缩和拆分是指收缩或者拆分索引的主分片数量。首先,我们要明白为什么需要进行索引的收缩和拆分呢? 在 elasticsearch 中,主节点管理分片是很大的工作量,降低集群整体分片数量可以降低 recovery 时间,减小集群状态的大小,降低集群的维护消耗。在很多情况下,经历了一段时间的运行以后,一些冷索引不会再有数据写入,将一些小分片合并可以降低集群的维护成本。 另一方面,如果在业务运行过程中发现前期的预估不足,业务量较大导致单个分片过大,则需要进行索引的拆分扩大主分片的数量。 一、索引收缩 Elasticsearch从5.0版本起提供了 shrink API,用于针对一些小索引缩小索引分片数。实际上并不对源索引进行操作,而是使用与源索引相同的配置创建一个新索引,仅仅降低分片数,索引分片缩小完成后,源索引可删除。 一个索引要能够被shrink API进行分片缩小,需要满足以下三个条件: 为了使分片分配更容易,可以先删除索引的复制分片,等完成了shrink操作以后再重新添加复制分片。 可以使用以下代码,实现删除所有的副本分片,将所有的主分片分配到同一个节点上,并且设置索引状态为只读: 重新分配源索引的分片可能需要一段时间,可以使用_cat API跟踪进度,或者使用集群 健康 API通过 wait_for_no_relocating_shards 参数等待所有分片完成重新分配。 当完成以上步骤以后就可以进行shrink操作了,以下为_shrink API的格式: 以下案例将索引my-index-000001缩小主分片到shrunk-my-index-000001索引。 特别注意:由于添加新文档时使用对分片数量取余获取目标分片,因此目标索引中请求的主分片数量必须是源索引中主分片数量的一个因子。例如,包含8个主分片的索引可以收缩为4个、2个或1个主分片,或者包含15个主分片片的索引可以收缩为5个、3个或1个主分片。如果索引中的分片数量是一个质数,那么它只能收缩为一个主分片。 如果当前索引是是一个data stream的写索引,则不允许进行索引收缩,需要对data stream进行rollover,创建一个新的写索引,才可以对当前索引进行收缩。 整个索引收缩的过程如下: 同样地,Elasticsearch还提供了Split API,用于将索引拆分到具有更多主分片的新索引。Split API的格式如下: 要完成整个Split的操作需要满足以下条件: 以下API请求可以将索引设置为只读: 如果当前索引是是一个data stream的写索引,则不允许进行索引拆分,需要对data stream进行rollover,创建一个新的写索引,才可以对当前索引进行拆分。 以下是使用Split API进行索引拆分的请求案例, Split API支持 settings 和 aliases 。 index.number_of_shards 指定的主分片的数量 必须是源分片数量的倍数。 索引拆分可以拆分的分片的数量由参数 index.number_of_routing_shards 决定,路由分片的数量指定哈希空间,该空间在内部用于以一致性哈希的形式在各个 shard 之间分发文档。 例如,将 number_of_routing_shards 设置为30(5 x 2 x 3)的具有5个分片的索引可以拆分为 以2倍 或 3倍的形式进行拆分。换句话说,可以如下拆分: 5 10 30(拆分依次为2和3) 5 15 30(拆分依次为3和2) 5 30(拆分6) index.number_of_routing_shards 是一个静态配置,可以在创建索引的时候指定,也可以在关闭的索引上设置。其默认值取决于原始索引中主分片的数量,默认情况下,允许按2的倍数分割 最多1024 个分片。但是,必须考虑主分片的原始数量。例如,使用5个分片创建的索引可以被分割为10、20、40、80、160、320,或最多640个分片。 如果源索引只有一个主分片,那么可以被拆分成为任意数量的主分片。 2.2、索引拆分的工作过程 2.3、为什么Elasticsearch不支持增量的重新分片? 大多数的键值存储都支持随着数据的增长实现自动分片的自动扩展,为什么Elasticsearch不支持呢? 最经典的方案在于新增一个分片,然后将新的数据存储到这个新增加的分片,但是这种方案在Elasticsearch中可能会造成索引的瓶颈,整体的结构会变得比较复杂,因为Elasticsearch需要去定位文档到底归属于在哪一个分片,这意味着需要使用不同的哈希方案重新平衡现有数据。 键值存储系统解决这个问题的方案一般是使用一致性哈希,当分片数从N增加到N+1时,一致性哈希只需要对1/N的key进行重新分配,例如redis集群的方案就是蕾丝如此。 但是Elasticsearch分片的底层实际上上是Lucene的索引,而从Lucene索引删除一小部分的数据,通常比键值存储系统的成本要高得多。所以Elasticsearch选择在索引层面上进行拆分,使用硬链接进行高效的文件复制,以避免在索引间移动文档。 对于仅追加数据而没有修改、删除等场景,可以通过创建一个新索引并将新数据推送到该索引,同时添加一个用于读操作的涵盖旧索引和新索引的别名来获得更大的灵活性。假设旧索引和新索引分别有M和N个分片,这与搜索一个有M+N个分片的索引相比没有任何开销。 2.4、如何监控Split的进度 使用Split API进行索引拆分,API正常返回并不意味着Split的过程已经完成,这仅仅意味着创建目标索引的请求已经完成,并且加入了集群状态,此时主分片可能还未被分配,副本分片可能还未创建成功。 一旦主分片完成了分配,状态就会转化为 initializing ,并且开始进行拆分过程,直到拆分过程完成,分片的状态将会变成 active 。 可以使用 _cat recovery API 来监控Split进程,或者可以使用集群 健康 API通过将 wait_for_status 参数设置为黄色来等待所有主分片分配完毕。 Elasticsearch Clone API可以用于Elasticsearch索引数据的复制和备份。 二、索引克隆API 索引克隆不会克隆源索引的元数据,包括别名、ILM阶段定义、CCR follower相关信息,克隆API将会复制除了index.number_of_replicas和index.auto_expand_replicas之外的所有配置,这两个特殊的配置可以在克隆API的请求中显式指定。Clone API的格式如下: 索引满足可以克隆的条件是: 参照之前讲过的内容,仍然可以通过将 index.blocks.write 设置为true来确保索引是可读的状态。以下是克隆API的案例: 注意: index.number_of_shards 的值必须与源索引的主分片数量一致。 三、索引克隆的过程 四、监控克隆的进度 使用Clone API进行索引的克隆,API正常返回并不意味着Clone的过程已经完成,这仅仅意味着创建目标索引的请求已经完成,并且加入了集群状态,此时主分片可能还未被分配,副本分片可能还未创建成功。 一旦主分片完成了分配,状态就会转化为 initializing ,并且开始进行克隆过程,直到克隆过程完成,分片的状态将会变成 active 。 可以使用 _cat recovery API 来监控Clone进程,或者可以使用集群 健康 API通过将 wait_for_status 参数设置为黄色来等待所有主分片分配完毕。 rollover API是Elasticsearch提供的一个很好用的功能。我们都知道在MySQL中一旦数据量比较大,可能会存在分库分表的情况,例如根据时间每个月一个表。rollover功能就类似这种情况,它的原理是先创建一个带别名的索引,然后设定一定的规则(例如满足一定的时间范围的条件),当满足该设定规则的时候,Elasticsearch会自动建立新的索引,别名也自动切换指向新的索引,这样相当于在物理层面自动建立了索引的分区功能,当查询数据落在特定时间内时,会到一个相对小的索引中查询,相对所有数据都存储在一个大索引的情况,可以有效提升查询效率。 rollover API会为data stream或者索引别名创建一个新的索引。(在Elasticsearch 7.9之前,一般使用索引别名的方式来管理时间序列数据,在Elasticsearch之后data stream取代了这个功能,它需要更少的维护,并自动与数据层集成)。 rollover API的效果依据待滚动的索引别名的情况不同而有不同的表现: 使用rollover API的时候如果指定新的索引的名称,并且原索引以“-”结束并且以数字结尾,那么新索引将会沿用名称并且将数字增加,例如原索引是 my-index-000001 那么新索引会是 my-index-000002 。 如果对时间序列数据使用索引别名,则可以在索引名称中使用日期来跟踪滚动日期。例如,可以创建一个别名来指向名为 的索引,如果在2099年5月6日创建索引,则索引的名称为 my-index-2099.05.06-000001 。如果在2099年5月7日滚动别名,则新索引的名称为 my-index-2099.05.07-000002 。 rollover API的格式如下: rollover API也支持Query Parameters和Request Body,其中Query parameters支持 wait_for_active_shards 、 master_timeout 、 timeout 和 dry_run ,特别说一下 dry_run ,如果将 dry_run 设置为 true ,那么这次请求不会真的执行,但是会检查当前索引是否满足 conditions 指定的条件,这对于提前进行测试非常有用。 Request Body支持 aliases 、 mappings 和 settings (这三个参数只支持索引,不支持data stream)和 conditions 。 特别展开讲一下 conditions 。这是一个可选参数,如果指定了 conditions ,则需要在满足 conditions 指定的一个或者多个条件的情况下才会执行滚动,如果没有指定则无条件滚动,如果需要自动滚动,可以使用ILM Rollover。 conditions 支持的属性有: 以下为rollover一个data stream的一个案例: 响应信息如下: 以下为rollover一个索引别名的一个案例: 2. 请求rollover API 如果别名的索引名称使用日期数学表达式,并且按定期间隔滚动索引,则可以使用日期数学表达式来缩小搜索范围。例如,下面的搜索目标是最近三天内创建的索引。 索引的冻结是Elasticsearch提供的一个用于减少内存开销的操作,这个功能在7.14版本中被标记为 Deprecated ,在Version 8以后,已经对堆内存的使用进行了改进,冻结和解冻的功能不再适用。 这里简单地进行操作演示,如果是7.x版本仍然可以作为参照。 一、索引冻结 索引被冻结以后除了在内存中维护其元数据之外,在集群上几乎没有任何的开销。被冻结以后,索引是只读的,所有的写操作都将会被阻塞,例如文档的写入、merge合并等。 API格式如下: 以下为索引冻结操作的代码案例: 注意,冻结索引将关闭该索引,并在同一个API调用中重新打开它,这将导致在短时间内主分配没有被分配,并导致集群变为红色,直到再次完成分配。 二、索引解冻 对应索引的冻结,解冻的API格式如下: 以下为索引解冻操作的代码案例: Elasticsearch提供了Resolve index API用于辅助进行索引的解析,根据提供的索引/别名/数据流的名称或者模式匹配,查询出当前集群中匹配的索引的信息。以下为API的格式: 案例如下: 这个API的作用多为辅助,实际使用不多,细节的参数可以参考官方的文档。 跟我一起奋斗成为Elastic专家

Spring Boot+Elasticsearch的集成中,@Document注解有什么作用?

《盗魂铃》(又名“二本金钱豹”、“八戒降妖”)

Spring Boot整合ElasticSearch实现增删改查基本示例

ElasticSearch被命名为大数据搜索引擎,在文件检索、数据存储方面具有天然的优势。而SpringBoot作为服务整合中间件,在服务组装方面是一款万能粘合器,本文主要提供Spring Boot整合ElasticSearch基本增删改示例。 ElasticSearch安装过程可参考博主之前笔文: https://www.toutiao.com/i6827758978567504392/ ElasticSearch基本介绍可参考博主之前笔文: https://www.toutiao.com/i6884427730096488971/ Maven工程引入:org.springframework.boot spring-boot-starter-data-elasticsearch注意:ElasticSearch版本号与Spring Boot版本号是有关联的,本文笔者Spring Boot版本号是2.1.6,因此安装的ElasticSearch版本号是7.7.0。 package com.opendi.generator.elasticsearch.model;import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType;import java.util.List;@Data @Document(indexName="post", type="post",shards=1,replicas = 0) public class Post { @Id private String id;private String title;@Field(type=FieldType.Nested) private List tags; } package com.opendi.generator.model;import lombok.Data;import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType;@Data @Document(indexName = "book", type = "_doc", shards = 1, replicas = 0) public class BookBean { @Id private String id; @Field(type = FieldType.Keyword) private String title; @Field(type = FieldType.Keyword) private String author; @Field(type = FieldType.Keyword) private String postDate;public BookBean(){}public BookBean(String id, String title, String author, String postDate){ this.id=id; this.title=title; this.author=author; this.postDate=postDate; }public String getId() { return id; }public void setId(String id) { this.id = id; }public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }public String getAuthor() { return author; }public void setAuthor(String author) { this.author = author; }public String getPostDate() { return postDate; }public void setPostDate(String postDate) { this.postDate = postDate; }@Override public String toString() { return "BookBean{" + "id="" + id + """ + ", title="" + title + """ + ", author="" + author + """ + ", postDate="" + postDate + """ + "}"; } }package com.opendi.generator.elasticsearch.mapper;import com.opendi.generator.elasticsearch.model.Post; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;public interface PostRepository extends ElasticsearchRepository { Page findByTitle(String title, Pageable pageable); } package com.opendi.generator.dao;import com.opendi.generator.model.BookBean; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;/** * 接口关系: * ElasticsearchRepository --> ElasticsearchCrudRepository --> PagingAndSortingRepository --> CrudRepository */ public interface BookRepository extends ElasticsearchRepository { //Optional findById(String id); Page findByAuthor(String author, Pageable pageable); Page findByTitle(String title, Pageable pageable); }使用了ElasticSearch里面的操作工具对数据进行操作。 package com.opendi.generator.elasticsearch.service;import com.opendi.generator.elasticsearch.model.Post; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest;import java.util.Optional;public interface PostService {Post save(Post post);Optional findOne(String id); Iterable findAll(); Page findByTitle(String title, PageRequest pageRequest); } 指定操作对象: package com.opendi.generator.elasticsearch.service.impl;import com.opendi.generator.elasticsearch.mapper.PostRepository; import com.opendi.generator.elasticsearch.model.Post; import com.opendi.generator.elasticsearch.service.PostService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service;import java.util.Optional;@Service public class PostServiceImpl implements PostService {@Autowired private PostRepository postRepository;@Override public Post save(Post post) { postRepository.save(post); return post; }@Override public Optional findOne(String id) { return postRepository.findById(id); }@Override public Iterable findAll() { return postRepository.findAll(); }@Override public Page findByTitle(String title, PageRequest pageRequest) { return postRepository.findByTitle(title, pageRequest); } } package com.opendi.generator.service;import com.opendi.generator.model.BookBean; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest;import java.util.List; import java.util.Optional;public interface BookService {Optional findById(String id); BookBean save(BookBean blog);void delete(BookBean blog);Optional findOne(String id); List findAll(); Page findByAuthor(String author, PageRequest pageRequest); Page findByTitle(String title, PageRequest pageRequest); }package com.opendi.generator.service.impl;import com.opendi.generator.dao.BookRepository; import com.opendi.generator.model.BookBean; import com.opendi.generator.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service;import java.util.List; import java.util.Optional;@Service("blogService") public class BookServiceImpl implements BookService {@Autowired @Qualifier("bookRepository") private BookRepository bookRepository;@Override public Optional findById(String id) { //CrudRepository中的方法 return bookRepository.findById(id); }@Override public BookBean save(BookBean blog) { return bookRepository.save(blog); }@Override public void delete(BookBean blog) { bookRepository.delete(blog); }@Override public Optional findOne(String id) { return bookRepository.findById(id); }@Override public List findAll() { return (List ) bookRepository.findAll(); }@Override public Page findByAuthor(String author, PageRequest pageRequest) { return bookRepository.findByAuthor(author,pageRequest); }@Override public Page findByTitle(String title, PageRequest pageRequest) { return bookRepository.findByTitle(title,pageRequest); } } 会调用ElasticSearch底层功能进行操作,能够实现ElasticSearch增删改操作。 连接服务器ElasticSearch连接配置: spring: data: elasticsearch: cluster-name: es2018 cluster-nodes: 10.172.8.154:9300 repositories: enabled: true elasticsearch: jest: uris: http:// 10.172.8.154:9200 增加连接配置,这样就能连接ElasticSearch客户端了。 ElasticSearch在Controller操作: package com.opendi.generator.controller;import com.opendi.generator.model.BookBean; import com.opendi.generator.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.Optional;@RestController public class ElasticController { @Autowired private BookService bookService;@RequestMapping("/book/{id}") @ResponseBody public BookBean getBookById(@PathVariable String id){ Optional opt =bookService.findById(id); BookBean book=opt.get(); System.out.println(book); return book; }@RequestMapping("/save") @ResponseBody public void Save(){ System.setProperty("es.set.netty.runtime.available.processors", "false"); BookBean book=new BookBean("1","ES入门教程","程裕强","2018-10-01"); System.out.println(book); bookService.save(book); }}package com.opendi.generator.elasticsearch.controller;import com.opendi.generator.elasticsearch.model.Post; import com.opendi.generator.elasticsearch.model.Tag; import com.opendi.generator.elasticsearch.service.PostService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList; import java.util.Arrays; import java.util.List;@Api(tags="ElasticSearch示例") @RestController public class PostController {@Autowired private PostService postService;@ApiOperation(value="得到ES结果") @GetMapping(value="getList") public List<page > getList()</page { List<page > list = new ArrayList<page >();</page </page Tag tag = new Tag(); tag.setId("1"); tag.setName("tech"); Tag tag2 = new Tag(); tag2.setId("2"); tag2.setName("elasticSearch"); Post post = new Post(); post.setId("1"); post.setTitle("This is post"); post.setTags(Arrays.asList(tag,tag2)); postService.save(post); Post post2 = new Post(); post2.setId("2"); post2.setTitle("Biding2"); post2.setTags(Arrays.asList(tag)); postService.save(post2); Page posts = postService.findByTitle("This is post", new PageRequest(0, 10)); Page posts2 = postService.findByTitle("Biding2", new PageRequest(0,10)); Page posts3 = postService.findByTitle("Biding2", new PageRequest(0,10)); list.add(posts); list.add(posts2); list.add(posts3); return list; } } 控制台打印:

WomccServices.Desc 是什么文件???

WomccServices.Desc 是优化大师生成的 是一个自动启动的文件 不是病毒也不是木马 不用担心. 这是通过优化大师路径所选择的 删除或者留着都无所谓的.http://zhidao.baidu.com/question/17600955.html?fr=qrl3

如何在CentOS 7上安装Elasticsearch,Logstash和Kibana

这个博客看一下ubuntu和centos差不多网页链接

英国GCSE十年级数学课程学什么?求各位大神给完整课程内容!!急!!

TopicWhat Will I Learn?Indices and standard formLaws of indices, including negative powers.Standard form notation and calculations.Factors and multiplesRevision of product of prime factors, HCF and LCM.Fractions, decimals and percentagesArithmetic of fractions.Conversion of recurring decimals to fractions.Use of a decimal multiplier for percentage increase and decrease.Compound interest, percentage profit and loss.AlgebraSimplifying algebraic fractions.Factorisation.Laws of indices in algebra.SequencesAlgebraic description of sequences.Straight line graphsEquation of a straight line.Graphical solution of simultaneous equations.Graphs of linear inequalities.Loci and constructionsLoci and constructions.TransformationsRevision of transformations.StatisticsFinding the median and quartiles.Estimating the mean from grouped data.Two-way tables, frequency polygons, boxplots.QuadraticsExpanding the product of linear expressions.Factorising quadratic expressions.Calculator skillsRounding and significant figures.Bounds.Trial and improvement.Angles and polygonsInterior and exterior angles of polygons.Area and volumeSurface area and volume of prisms.Converting m2 to cm2, etc.Units and compound measuresImperial and metric equivalents.Speed and density.ProbabilityRevision of probability.FormulaeChanging the subject of a formula.Simultaneous equationsAlgebraic solution of linear simultaneous equations.Similar triangles and enlargementCalculations involving similar shapes.Enlargement with negative and fractional scale factors.TrigonometryRevision of Pythagoras" theorem.Trigonometry in right-angled triangles.Probability tree diagramsProbability tree diagrams.StatisticsCumulative frequency graphs and histograms.QuadraticsFactorisation of quadratic expressions.Solution of quadratic equations by factorisation and the quadratic formula.Curved graphsGraphs of quadratic, cubic, reciprocal and exponential functions.ProportionDirect and inverse proportion.Angles and geometrical proofRevision of angles and geometrical proof.Circle theoremsGeometrical problem solving including the circle theorems.Area and volumeSurface area and volume of a sphere, cone, cylinder and pyramid.Ratios of areas and volumes.CongruenceConditions for congruency.Fractional indicesManipulation of fractional indices.SurdsManipulation of surds.Sine and cosine rulesTrigonometry in non-right-angled triangles.3D Pythagoras and trigonometryApplication to 3D problems.Graphs of trigonometric functionsGraphs of y=sinx and y=cosx.Transformation of graphsTransformation of graphs.Algebraic fractionsManipulation of algebraic fractions.VectorsVector notation and solution of geometrical problems.Completing the squareCompleting the square on quadratic expressions.Simultaneous equationsSolution of simultaneous equations with one linear and one quadratic equation.The equation of the circle.ProofGeneralisation and proof.我们学校的,因为是私校,比较难,不过公校的我也可以上,比较容易

微软MCP认证有用吗?是不是只有拿了MCP认证0才能继续拿其他的什么MCSE.MCSD,MCDBA?

没啥用 我还考了个MCP290的 MCP是微软认证体系中最基础的证书,考生只需要参加一门考试就可以获得证书,它所代表你获得对应微软产品或技术的证明。因为MCP证书获得的门槛太低,所以MCP证书的效力并不像其他的微软认证证书那样显赫,在业界的认可程度也并不高,所以IT认证考试资源网建议那些有志于从事IT行业的考生们还是尽量选择象MCSE2003和MCITP MCPD这样含金量比较高的证书。MCP跟拿MCSE.MCSD,MCDBA没什么大的挂钩

mcse、ccna、cissp证书能跟我介绍一下吗

mcse ccna 是国际认证哦,这感觉不是一句话两句话说得清楚的,最好自己了解一下,或参加相关的培训!

Elasticsearch的缓存机制简介

根据名称其实就能理解,这是属于Node级别的缓存。主要用于缓存Filter中的Query结果,基于LRU策略,当缓存满了的情况下,会自动去除一个最近最少被使用的Query Cache。 缓存分为两个级别,第一级是 Query ,第二级是 Segmemt ,就像是 Map<Query, Map<Segment, DocIdSet>> 这种结构一样。 DocIdSet 使用的数据结构是 Bitset 。 indices.queries.cache.size 集群中的每个节点都必须有的静态配置,用来控制用来缓存的内存大小,默认是10%,支持两种格式一种是百分数,代表占节点heap的百分比,另一种则是精确的值,比如512mb。 indices.queries.cache.count 在官方文档并没有写,这是一个节点级别的配置,可以在elasticsearch.yml中配置,控制缓存的总数量。 indices.queries.cache.all_segments 用于是否在所有 Segment 上启用缓存,默认是false,不会对文档数小于100000或者小于整个索引大小的3%的 Segment 进行缓存。 index.queries.cache.enabled 是属于index级别的配置,用来控制是否启用缓存,默认是开启的。 Segment 中文档数大于100000或者大于整个所以大小的3%。 请注意如果想要索引所有段,请设置indices.queries.cache.all_segments 缓存不会失效,而是通过判断文档是否符合 Query 的条件,如果符合条件的话则会将文档加入到 Bitset 中。 主要用于 sort 以及 aggs 的字段。这会把字段的值加载到内存中,以便于快速访问。 field data cache 的构建非常昂贵,因此最好能分配足够的内存以保障它能长时间处于被加载的状态。 indices.fielddata.cache.size 用来控制缓存的大小,支持两种格式,一种是百分数,代表占节点heap的百分比,另一种是精确值,如10gb,默认是无限。 顾名思义,Shard级别的缓存。默认的主要用于缓存size=0的请求, aggs 和 suggestions ,还有就是 hits.total 。 需要注意,每当分片索引refresh的时候,如果数据发生了实际变化,那么缓存就会自动失效。所以呢,refresh时间越长,那么缓存的时间也就越长。缓存采用的也是LRU策略。 index.requests.cache.enable 这个参数用来控制是否启用分片级别的缓存,默认是false 通过url传参方式request_cache=true indices.requests.cache.size 用来控制缓存在 heap 中的大小,默认是1%。 用于缓存新索引的数据,用于缓存新索引的数据,当空间填满之后,会将数据写到磁盘上成为一个新的段。

ElasticSearch部署架构和容量规划

前面介绍了ElasticSearch原理和使用相关的内容,在生产环境如何比较科学的进行容量规划、部署、调优、排查问题呢,业界和官方也对相关的问题进行总结,我这边也结合自己的经验对这些使用ElasticSearch经常遇到的问题进行了总结。其中主要包括以下三大模块: ElasticSearch有多种类型的节点,在前面概述和核心也已经介绍过了。在这里可以重新回顾下。ElasticSearch的部署节点类型如下: 主节点及其候选节点,负责集群状态(cluster state)的管理 配置项:node.master,默认为true 数据节点,负责数据存储及处理客户端请求 配置项:node.data,默认为true ingest节点,负责数据处理,脚本执行 配置项:node.ingest,默认为true 协调节点 配置项:设置上面三个参数全部为false,那么它就是一个纯协调节点 机器学习节点,收费属于x-pack 在生产环境部署推荐配置整体思路就是:尽量是一个节点只承担一个角色。 因为不同的节点所需要的计算机资源都不一样。职责分离后可以按需扩展互不影响。 资源要求:中高CPU;中高内存;中低磁盘 一般在生产环境中配置3台 一个集群只有1台活跃的主节点,负责分片管理,索引创建,集群管理等操作 资源要求:CPU、内存、磁盘要求都高 资源要求:高配置CPU;中等配置的RAM;低配置的磁盘 资源要求:一般中高CPU;中高内存;低磁盘 协调节点扮演者负载均衡、结果的聚合,在大型的es集群中条件允许可以使用高配的cpu和内存。因为如果客户端发起了深度分页等请求可能会导致oom,这个在之前也有过分析。 注意: 如果和数据节点或者Coordinate节点混合部署,数据节点本来相对有比较大的内存占用。 而Coordinate节点有时候可能会有开销很高的查询导致OOM,这些甚至都有可能影响Master节点,导致集群的不稳定。 搭建一个es集群是由模式可循的。 这是一个基础版的职责分离的部署架构: 但是如果大量的聚合查询等操作,这种架构不太适合了。 当系统中有大量的复杂查询或者聚合时候,我们可增加Coordinating节点,增加查询的性能,这里增加了负载均衡层,通过负载均衡扩展时应用程序无感知。 这样部署部署相互影响,写入多的话,多部署ingetst节点,读的时候聚合查询较多可以多部署协调节点,存储数据量大,可以适当对数据节点进行调优。 我们知道数据有冷热之分,比如写入频繁的日志数据,近期的索引将会频繁写入。es根据数据这些特征引入了hot节点和warm节点。 使用ssd,该节点上的索引不断的有新文档写入和查询,对cpu、io的要求较高。 可以使用HDD,上面的索引不会有写入,查询较少。上面只保存只读索引或者旧索引,使用大容量便宜的机械硬盘。 配置步骤: 针对多机房灾备,ElasticSearch业界有多种不同的通用解决方案: 一个集群中的节点分布在不同的机房 应用程序同时将数据写入两个集群 应用程序先将数据写入消息队列,然后由下游的消费者消费并写入集群 ElasticSearch官方的跨集群复制功能,基于文档操作实现订阅复制 定期将索引备份到外部存储,如hdfs等设备 写请求交给网关,网关实时写入主集群,然后异步写备集群 如下是基于CCR跨集群复制的部署架构,因为篇幅有限,异地多活又是一个很大的话题,其它方案和其细节可以查阅相关资料。 我们知道当es集群的节点数大于索引的分片数时,集群将无法通过水平扩展提升集群的性能。而分片数过多,对于聚合查询以及集群的元数据管理也都有影响。我们可以总结为: 分片数量较多 优点: 缺点: 通常建议一个集群总分片数小于10w。 如何设计分片的数量呢?一个分片保持多大的数据量比较合适呢? 我们需要根据使用场景来设置: 避免使用非常大的分片,因为这会对群集从故障中恢复的能力产生负面影响。而每个分片也会消耗相应的文件句柄,内存和CPU资源,分片太多会互相竞争,影响性能。 主分片数一旦确定就无法更改,只能新建创建并对数据进行重新索引(reindex),虽然reindex会比较耗时,但至少能保证你不会停机。所以我们一定要科学的设计分片数。 这里摘录于官方关于分片大小的建议: 主分片与副本都能处理查询请求,它们的唯一区别在于只有主分片才能处理索引请求。副本对搜索性能非常重要,同时用户也可在任何时候添加或删除副本。额外的副本能给带来更大的容量,更高的呑吐能力及更强的故障恢复能力 3.1.3. 小结 根据实际经验我们稍微总结下: 对于数据量较小(100GB以下)的index 对于数据量较大(100GB以上)的index: 综合考虑整个index的shard数量,如果shard数量(不包括副本)超过50个,就很可能引发拒绝率上升的问题,此时可考虑把该index拆分为多个独立的index,分摊数据量,同时配合routing使用,降低每个查询需要访问的shard数量。 关闭交换分区的方法是: 这里是官方的jvm推荐配置链接: https://www.elastic.co/cn/blog/a-heap-of-trouble es的节点提供查询的时候使用较多的内存来存储查询缓存,es的lucene写入到磁盘也会先缓存在内存中,我们开启设计这个es节点时需要根据每个节点的存储数据量来进行判断。这里有一个流行的推荐比例配置: 示例: 有一个业务的数据量预估实际有1T,我们把副本设置1个,那么es中总数据量为2T。 这里31G表示的是jvm设置不超过32g否则不会使用java的指针压缩优化了。 前面也提到过,数据节点推荐使用ssd 可以考虑: 写入的目标在于增大写入的吞吐量,这里主要从两个方面进行优化: 这里可以针对myindex索引优化的示例: 首先有几个原则我们需要清楚: 我们可以通过health相关的api进行查看 我们可以使用profile api来定位慢查询。 在查询条件中设置profile为true的参数,将会显示查询经历的细节。 其结果为: 这里会返回一个shards列表。其中: 主要包含了如下信息: Profile API让我们清楚地看到查询耗时。提供了有关子查询的详细信息,我们可以清楚地知道在哪个环节查询慢,另外返回的结果中,关于Lucene的详细信息也让我们深入了解到ES是如何执行查询的。 ES记录了两类慢日志: 慢搜索日志 用来记录哪些查询比较慢,每个节点可以设置不同的阈值。 之前我们已经详细分析了ES的搜索由两个阶段组成: 慢搜索日志给出了每个阶段所花费的时间和整个查询内容本身。慢搜索日志可以为查询和取回阶段单独设置以时间为单位的阈值,在定义好每个级别的时间后,通过level决定输出哪个级别的日志。 示例如下 前面参考官方链接: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-modules-slowlog.html 如果出现节点占用CPU很高,我们需要知道CPU在运行什么任务,一般通过线程堆栈来查看。 这里有两种方式可以查看哪些线程CPU占用率比较高: 这里推荐使用hot_threads api 通过返回的结果可以看到什么线程占用更高,正在做什么操作。更详细的内容可以参考官网: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-hot-threads.html 4.3.2 内存使用率过高 1)缓存类型 首先我们需要了解ES中的缓存类型,缓存主要分成如图所示三大类,如下图所示,一个es节点的内存结构: Node Query Cache(Filter Context) Shard Query Cache(Cache Query的结果) Fielddata Cache Segments Cache (segments FST数据的缓存),为了加速查询,FST永驻堆内内存,无法被GC回收。该部分内存无法设置大小,长期占用50%~70%的堆内存,只能通过delete index,close index以及force-merge index释放内存 ES底层存储采用Lucene(搜索引擎),写入时会根据原始数据的内容,分词,然后生成倒排索引。查询时,先通过查询倒排索引找到数据地址(DocID)),再读取原始数据(行存数据、列存数据)。 但由于Lucene会为原始数据中的每个词都生成倒排索引,数据量较大。所以倒排索引对应的倒排表被存放在磁盘上。 这样如果每次查询都直接读取磁盘上的倒排表,再查询目标关键词,会有很多次磁盘IO,严重影响查询性能。为了解磁盘IO问题,Lucene引入排索引的二级索引FST[Finite State Transducer]。原理上可以理解为前缀树,加速查询 2)节点的内存查看 3)案例分析 如果节点出现了集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行Full GC。 常见原因: Segments个数过多,导致Full GC 我们可以通过查看ElasticSearch的内存分析命令发现: segments.memory占用很大空间。 解决方案: Field data cache 过大,导致Full GC 我们可以查看ElasticSearch的内存使用,发现fielddata.memory.size占用很大空间。同时,数据不存在写入和更新,也执行过segments merge。 解决方案: 复杂的嵌套聚合,导致集群Full GC 节点响应缓慢,持续进行Full GC。导出Dump分析。发现内存中有大量 bucket对象,查看日志,发现复杂的嵌套聚合 解决方案: 4)断路器 es有多种断路器,我们可以合理使用,避免不合理操作引发的OOM,每个断路器可以指定内存使用的限制。 关于es的断路器使用可以参考官网文档: https://www.elastic.co/cn/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker 在排查es问题时,我们会使用一些常见的命令来分析cpu、io、网络等问题。常见的命令如下 我们这里按照1s的频率输出磁盘信息 如果想查看和进程关联的信息,可以使用pidstat或者iotop。 例如,下面为iotop的输出结果 sar命令可以诊断操作系统内存相关情况。 PS:我们需要关闭内存交换,内存交换会严重损害性能 。 我们知道,操作系统有内核态和用户态,该命令可以输出相关信息 Recv-Q和Send-Q代表该连接在内核中等待发送和接收的数据长度。 如果改数据太多,可能原因为应用程序处理不及时或者对端的数据接收不及时,比如网络拥塞之类 本片文章先介绍了es的部署架构,回顾了es节点类型以及它们的配置方式,也了解了不同类型对硬件的要求不一样。然后总结了几种不同的架构模式,比如基础部署、读写分离、冷热分离、异地多活等架构模式,在生产环境中一般我们推荐读写分离架构模式,如果可以最好加上冷热分离,不过配置可能稍微复杂点。 对于容量规划与调优,首先要明确存储的数据量和使用场景,推荐内存磁盘比为:搜索类比例(1:16),日志类(1:48);比如2T的总数据,搜索如果要保持良好的性能的话,每个节点31*16=496G。每个节点实际有400G的存储空间。那么2T/400G,则需要5个es存储节点,每个节点分片数多少合适,文中也有介绍。副本分片数需要根据我们的容错需求。我们还总结了集群配置和jvm配置相关的优化。 es的使用优化,我们分别总结了写入和查询的优化。写入是其单次数据量、索引refresh、分词等情况都会影响其吞吐量,我们需要根据实际情况来优化。针对于查询,我们可以使用api工具进行分析,分析慢耗时发在在哪一步。当es集群出现异常时,如cpu过高、内存fullgc、卡顿、变红,我们逐一分析了可能的原因和解决办法,同时也介绍了一些常见的诊断工具和监控api。 我们需要先了解es内部运作的原理,这样才能根据实际情况正确的设置集群参数和数据模型,还需要结合实际工作遇到的问题不断的总结经验,才能用好ElasticSearch。

sixth form 是不是英国高中?那么forth和fifth form就是GCSE第一二年吗?

Lower Fifth is Year 10 and Upper Fifth is Year 11 Year 10-GCSE第一年 Year11-第二年

突破性能瓶颈!ElasticSearch百亿级数据检索优化案例

本文中的数据平台已迭代三个版本,从头开始遇到很多常见的难题,终于有片段时间整理一些已完善的文档,在此分享以供所需朋友的。实现参考,少走些弯路,在此篇幅中偏重于ES的优化,目前生产已存储百亿数据,性能良好,关于HBase,Hadoop的设计优化估计有很多文章可以参考,不再赘述。 项目背景:在一业务系统中,部分表每天的数据量过亿,已按天分表,但业务上受限于按天查询,并且DB中只能保留3个月的数据(硬件高配),分库代价较高。 改进版本目标: 谈到优化必须能了解组件的基本原理,才容易找到瓶颈所在,以免走多种弯路,先从ES的基础结构说起(如下图): 一些基本概念: ES依赖一个重要的组件Lucene,关于数据结构的优化通常来说是对Lucene的优化,它是集群的一个存储于检索工作单元,结构如下图: 在Lucene中,分为索引(录入)与检索(查询)两部分,索引部分包含 分词器、过滤器、字符映射器 等,检索部分包含 查询解析器 等。一个Lucene索引包含多个segments,一个segment包含多个文档,每个文档包含多个字段,每个字段经过分词后形成一个或多个term。 通过Luke工具查看ES的lucene文件如下,主要增加了_id 和 _source字段: Lucene 索引文件结构主要的分为:词典、倒排表、正向文件、DocValues等,如下图: Lucene 随机三次磁盘读取比较耗时。其中.fdt文件保存数据值损耗空间大,.tim和.doc则需要SSD存储提高随机读写性能。 另外一个比较消耗性能的是打分流程,不需要则可屏蔽。 关于DocValues: 倒排索引解决从词快速检索到相应文档ID, 但如果需要对结果进行排序、分组、聚合等操作的时候则需要根据文档ID快速找到对应的值。 通过倒排索引代价缺很高:需迭代索引里的每个词项并收集文档的列里面 token。这很慢而且难以扩展:随着词项和文档的数量增加,执行时间也会增加。Solr docs对此的解释如下: 在lucene 4.0版本前通过FieldCache,原理是通过按列逆转倒排表将(field value ->doc)映射变成(doc -> field value)映射,问题为逐步构建时间长并且消耗大量内存,容易造成OOM。 DocValues是一种列存储结构,能快速通过文档ID找到相关需要排序的字段。在ES中,默认开启所有(除了标记需analyzed的字符串字段)字段的doc values,如果不需要对此字段做任何排序等工作,则可关闭以减少资源消耗。 ES中一个索引由一个或多个lucene索引构成,一个lucene索引由一个或多个segment构成,其中segment是最小的检索域。 数据具体被存储到哪个分片上:shard = hash(routing) % number_of_primary_shards 默认情况下 routing参数是文档ID (murmurhash3),可通过 URL中的 _routing 参数指定数据分布在同一个分片中,index和search的时候都需要一致才能找到数据,如果能明确根据_routing进行数据分区,则可减少分片的检索工作,以提高性能。 在我们的案例中,查询字段都是固定的,不提供全文检索功能,这也是几十亿数据能秒级返回的一个大前提: 1、ES仅提供字段的检索,仅存储HBase的Rowkey不存储实际数据。 2、实际数据存储在HBase中,通过Rowkey查询,如下图。 3、提高索引与检索的性能建议,可参考官方文档(如 https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html )。 一些细节优化项官方与其他的一些文章都有描述,在此文章中仅提出一些本案例的重点优化项。 1、批量写入,看每条数据量的大小,一般都是几百到几千。 2、多线程写入,写入线程数一般和机器数相当,可以配多种情况,在测试环境通过Kibana观察性能曲线。 3、增加segments的刷新时间,通过上面的原理知道,segment作为一个最小的检索单元,比如segment有50个,目的需要查10条数据,但需要从50个segment,分别查询10条,共500条记录,再进行排序或者分数比较后,截取最前面的10条,丢弃490条。在我们的案例中将此 "refresh_interval": "-1" ,程序批量写入完成后进行手工刷新(调用相应的API即可)。 4、内存分配方面,很多文章已经提到,给系统50%的内存给Lucene做文件缓存,它任务很繁重,所以ES节点的内存需要比较多(比如每个节点能配置64G以上最好)。 5、磁盘方面配置SSD,机械盘做阵列RAID5 RAID10虽然看上去很快,但是随机IO还是SSD好。 6、 使用自动生成的ID,在我们的案例中使用自定义的KEY,也就是与HBase的ROW KEY,是为了能根据rowkey删除和更新数据,性能下降不是很明显。 7、关于段合并,合并在后台定期执行,比较大的segment需要很长时间才能完成,为了减少对其他操作的影响(如检索),elasticsearch进行阈值限制,默认是20MB/s, 可配置的参数:"indices.store.throttle.max_bytes_per_sec" : "200mb" (根据磁盘性能调整) 合并线程数默认是:Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)),如果是机械磁盘,可以考虑设置为1:index.merge.scheduler.max_thread_count: 1, 在我们的案例中使用SSD,配置了6个合并线程。 1、关闭不需要字段的doc values。 2、尽量使用keyword替代一些long或者int之类,term查询总比range查询好 (参考lucene说明 http://lucene.apache.org/core/7_4_0/core/org/apache/lucene/index/PointValues.html )。 3、关闭不需要查询字段的 _ source 功能,不将此存储仅ES中,以节省磁盘空间。 4、评分消耗资源,如果不需要可使用filter过滤来达到关闭评分功能,score则为0,如果使用constantScoreQuery则score为1。 5、关于分页: (1)from + size: 每分片检索结果数最大为 from + size,假设from = 20, size = 20,则每个分片需要获取 20 x 20 = 400条数据,多个分片的结果在协调节点合并(假设请求的分配数为5,则结果数最大为 400 * 5 = 2000条) 再在内存中排序后然后20条给用户。这种机制导致越往后分页获取的代价越高,达到50000条将面临沉重的代价,默认from + size默认如下: index.max_result_window:10000 (2) search_after: 使用前一个分页记录的最后一条来检索下一个分页记录,在我们的案例中,首先使用from+size,检索出结果后再使用search_after,在页面上我们限制了用户只能跳5页,不能跳到最后一页。 (3) scroll 用于大结果集查询,缺陷是需要维护scroll_id 6、关于排序:我们增加一个long字段,它用于存储时间和ID的组合(通过移位即可),正排与倒排性能相差不明显。 7、关于CPU消耗,检索时如果需要做排序则需要字段对比,消耗CPU比较大,如果有可能尽量分配16cores以上的CPU,具体看业务压力。 8、关于合并被标记删除的记录,我们设置为0表示在合并的时候一定删除被标记的记录,默认应该是大于10%才删除: "merge.policy.expunge_deletes_allowed": "0"。 优化效果评估基于基准测试,如果没有基准测试无法了解是否有性能提升,在这所有的变动前做一次测试会比较好。在我们的案例中: 1、单节点5千万到一亿的数据量测试,检查单点承受能力。 2、集群测试1亿-30亿的数量,磁盘IO/内存/CPU/网络IO消耗如何。 3、随机不同组合条件的检索,在各个数据量情况下表现如何。 4、另外SSD与机械盘在测试中性能差距如何。 性能的测试组合有很多,通常也很花时间,不过作为评测标准时间上的投入有必要,否则生产出现性能问题很难定位或不好改善。对于ES的性能研究花了不少时间,最多的关注点就是lucene的优化,能深入了解lucene原理对优化有很大的帮助。 目前平台稳定运行,百亿的数据查询100条都在3秒内返回,前后翻页很快,如果后续有性能瓶颈,可通过扩展节点分担数据压力。
 1 2 3 4  下一页  尾页