eskc算法
㈠ 最小生成树 普里姆算法和克鲁斯卡尔算法
kruskal算法的时间复杂度主要由排序方法决定,其排序算法只与带权边的个数有关,与图中顶点的个数无关,当使用时间复杂度为O(eloge)的排序算法时,克鲁斯卡算法的时间复杂度即为O(eloge),因此当带权图的顶点个数较多而边的条数较少时,使用克鲁斯卡尔算法构造最小生成树效果最好!
克鲁斯卡尔算法
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
普里姆算法
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,TV 是 WN 上最小生成树中顶点的集合,TE 是最小生成树中边的集合。显然,在算法执行结束时,TV=V,而 TE 是 E 的一个子集。在算法开始执行时,TE 为空集,TV 中只有一个顶点,因此,按普里姆算法构造最小生成树的过程为:在所有“其一个顶点已经落在生成树上,而另一个顶点尚未落在生成树上”的边中取一条权值为最小的边,逐条加在生成树上,直至生成树中含有 n-1条边为止。
--以上传自http://hi..com/valyanprogramming/blog/item/1bc960e6095f9726b93820d9.html
1.Kruskal
//题目地址:http://acm.pku.e.cn/JudgeOnline/problem?id=1258
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
struct node
{
int v1;
int v2;
int len;
}e[10000];//定义边集
int cmp(const void *a,const void *b)//快排比较函数
{
return ((node*)a)->len-((node*)b)->len;
}
int v[100],a[100][100];//v为点集
void makeset(int n)
{
for(int i=0;i<n;i++)
v[i]=i;
}
int find(int x)
{
int h=x;
while(h!=v[h])
h=v[h];
return h;
}
int main()
{
int n,i,j,r1,r2,p,total;
while(scanf("%d",&n)!=EOF)
{
p=0;
total=0;
makeset(n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
e[p].v1=i;
e[p].v2=j;
e[p].len=a[i][j];
p++;
}
}
qsort(e,p,sizeof(e[0]),cmp);
for(i=0;i<p;i++)
{
r1=find(e[i].v1);
r2=find(e[i].v2);
if(r1!=r2)
{
total+=e[i].len;
v[r1]=r2;
}
}
printf("%d\n",total);
}
system("pause");
return 0;
}
2.Prim
//题目地址同上
#include <iostream>
using namespace std;
#define M 101
#define maxnum 100001
int dis[M][M];
int prim(int n)
{
bool used[M]={};
int d[M],i,j,k;
for(i=1; i<=n; i++)
d[i] = dis[1][i];
used[1] = true;
int sum=0;
for(i=1; i<n; i++){
int temp=maxnum;
for(j=1; j<=n; j++){
if( !used[j] && d[j]<temp ){
temp = d[j];
k = j;
}
}
used[k] = true;
sum += d[k];
for(j=1; j<=n; j++){
if( !used[j] && dis[k][j]<d[j] )
d[j] = dis[k][j]; // 与Dijksta算法的差别之处
}
}
return sum;
}
int main()
{
int n,i,j;
while( cin>>n ){
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
scanf("%d",&dis[i][j]);
if( !dis[i][j] )
dis[i][j] = maxnum;
}
}
cout<<prim(n)<<endl;
}
return 0;
}
代码来自网络
㈡ es使用与原理6 -- 聚合分析剖析
有些聚合分析的算法,是很容易就可以并行的,比如说max
有些聚合分析的算法,是不好并行的,比如说,count(distinct),并不是说,在每个node上,直接就出一些distinct value,就可以的,因为数据可能会很多,假设图中的协调节点3百万个数据去重后还剩下100万distinct的数据,那么内存需要来存储这100万条数据,这是不可能的
es会采取近似聚合的方式,就是采用在每个node上进行近估计的方式,得到最终的结论,cuont(distcint),100万,1050万/95万 --> 5%左右的错误率
近似估计后的结果,不完全准确,但是速度会很快,一般会达到完全精准的算法的性能的数十倍
precision_threshold优化准确率和内存开销
brand去重,如果brand的unique value,在100个以内,小米,长虹,三星,TCL,HTL。。。
在多少个unique value以内,cardinality,几乎保证100%准确
cardinality算法,会占用precision_threshold * 8 byte 内存消耗,100 * 8 = 800个字节
占用内存很小。。。而且unique value如果的确在值以内,那么可以确保100%准确
100,数百万的unique value,错误率在5%以内
precision_threshold,值设置的越大,占用内存越大,1000 * 8 = 8000 / 1000 = 8KB,可以确保更多unique value的场景下,100%的准确
field,去重,count,这时候,unique value,10000,precision_threshold=10000,10000 * 8 = 80000个byte,80KB
doc value正排索引
搜索+聚合 是怎么实现的?
假设是倒排索引实现的
倒排索引来实现是非常不现实的,因为我们搜索的那个字段search_field 有可能是分词的,这就需要去扫描整个索引才能实现聚合操作,效率是及其低下的。
正排索引结构:
doc2: agg1
doc3: agg2
1万个doc --> 搜 -> 可能跟搜索到10000次,就搜索完了,就找到了1万个doc的聚合field的所有值了,然后就可以执行分组聚合操作了
doc value原理
1、doc value原理
(1)index-time生成
PUT/POST的时候,就会生成doc value数据,也就是正排索引
(2)核心原理与倒排索引类似
正排索引,也会写入磁盘文件中,然后呢,os cache先进行缓存,以提升访问doc value正排索引的性能
如果os cache内存大小不足够放得下整个正排索引,doc value,就会将doc value的数据写入磁盘文件中
(3)性能问题:给jvm更少内存,64g服务器,给jvm最多16g
es官方是建议,es大量是基于os cache来进行缓存和提升性能的,不建议用jvm内存来进行缓存,那样会导致一定的gc开销和oom问题
给jvm更少的内存,给os cache更大的内存
64g服务器,给jvm最多16g,几十个g的内存给os cache
os cache可以提升doc value和倒排索引的缓存和查询效率
2、column压缩
doc1: 550
doc2: 550
doc3: 500
合并相同值,550,doc1和doc2都保留一个550的标识即可
(1)所有值相同,直接保留单值
(2)少于256个值,使用table encoding模式:一种压缩方式
(3)大于256个值,看有没有最大公约数,有就除以最大公约数,然后保留这个最大公约数
重点:
对分词的field,直接执行聚合操作,会报错,大概意思是说,你必须要打开fielddata,然后将正排索引数据加载到内存中,才可以对分词的field执行聚合操作,而且会消耗很大的内存
先修改 字段的fielddata属性为true,再查 就能查找到数据
当然,我们也可以使用内置field(keyword)不分词,对string field进行聚合,如果对不分词的field执行聚合操作,直接就可以执行,不需要设置fieldata=true
分词field+fielddata的工作原理
doc value --> 不分词的所有field,可以执行聚合操作 --> 如果你的某个field不分词,那么在index-time,就会自动生成doc value --> 针对这些不分词的field执行聚合操作的时候,自动就会用doc value来执行
分词field,是没有doc value的。。。在index-time,如果某个field是分词的,那么是不会给它建立doc value正排索引的,因为分词后,占用的空间过于大,所以默认是不支持分词field进行聚合的
分词field默认没有doc value,所以直接对分词field执行聚合操作,是会报错的
对于分词field,必须打开和使用fielddata,完全存在于纯内存中。。。结构和doc value类似。。。如果是ngram或者是大量term,那么必将占用大量的内存。。。
如果一定要对分词的field执行聚合,那么必须将fielddata=true,然后es就会在执行聚合操作的时候,现场将field对应的数据,建立一份fielddata正排索引,fielddata正排索引的结构跟doc value是类似的,
但是只会讲fielddata正排索引加载到内存中来,然后基于内存中的fielddata正排索引执行分词field的聚合操作
如果直接对分词field执行聚合,报错,才会让我们开启fielddata=true,告诉我们,会将fielddata uninverted index,正排索引,加载到内存,会耗费内存空间
为什么fielddata必须在内存?因为大家自己思考一下,分词的字符串,需要按照term进行聚合,需要执行更加复杂的算法和操作,如果基于磁盘和os cache,那么性能会很差
我们是不是可以预先生成加载fielddata到内存中来???
query-time的fielddata生成和加载到内存,变为index-time,建立倒排索引的时候,会同步生成fielddata并且加载到内存中来,这样的话,对分词field的聚合性能当然会大幅度增强
㈢ ES集群原理与搭建
查看集群健康状况:URL+ /GET _cat/health
Cluster
代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
Shards
代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
replicas
代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
Recovery
代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
(2)、ES为什么要实现集群
在单台ES服务器节点上,随着业务量的发展索引文件慢慢增多,会影响到效率和内存存储问题等。
我们可以采用ES集群,将单个索引的分片到多个不同分布式物理机器上存储,从而可以实现高可用、容错性等。
ES集群中索引可能由多个分片构成,并且每个分片可以拥有多个副本。通过将一个单独的索引分为多个分片,我们可以处理不能在一个单一的服务器上面运行的大型索引,简单的说就是索引的大小过大,导致效率问题。不能运行的原因可能是内存也可能是存储。由于每个分片可以有多个副本,通过将副本分配到多个服务器,可以提高查询的负载能力。
(3)、ES是如何解决高并发
ES是一个分布式全文检索框架,隐藏了复杂的处理机制,内部使用 分片机制、集群发现、分片负载均衡请求路由。
Shards 分片:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
Replicas分片:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
1、每个索引会被分成多个分片shards进行存储,默认创建索引是分配5个分片进行存储。每个分片都会分布式部署在多个不同的节点上进行部署,该分片成为primary shards。
注意:索引的主分片primary shards定义好后,后面不能做修改。
2、为了实现高可用数据的高可用,主分片可以有对应的备分片replics shards,replic shards分片承载了负责容错、以及请求的负载均衡。
注意: 每一个主分片为了实现高可用,都会有自己对应的备分片,主分片对应的备分片不能存放同一台服务器上。主分片primary shards可以和其他replics shards存放在同一个node节点上。
3、documnet routing(数据路由)
当客户端发起创建document的时候,es需要确定这个document放在该index哪个shard上。这个过程就是数据路由。
路由算法:shard = hash(routing) % number_of_primary_shards
如果number_of_primary_shards在查询的时候取余发生的变化,无法获取到该数据
注意:索引的主分片数量定义好后,不能被修改
高可用视图分析(下图所示:上面的图,如果节点1与节点2宕机了,es集群数据就不完整了。下面图,如果节点1与节点2宕机了,es集群数据还是完整的)
(1)、服务器环境
准备三台服务器集群
| 服务器名称 | IP地址 |
| node-1 | 192.168.212.182 |
| node-2 | 192.168.212.183 |
| node-3 | 192.168.212.184 |
(2)、关闭防火墙
(3)、**** http://192.168.212.185:9200/_cat/nodes?pretty
*号表示为master节点
注意:
注意克隆data文件会导致数据不同步
报该错误解决办法 :
failed to send join request to master
因为克隆导致data文件也克隆呢,直接清除每台服务器data文件。
㈣ 进化算法的特点
进化计算是一种具有鲁棒性的方法,能适应不同的环境不同的问题,而且在大多数情况下都能得到比较满意的有效解。他对问题的整个参数空间给出一种编码方案,而不是直接对问题的具体参数进行处理,不是从某个单一的初始点开始搜索,而是从一组初始点搜索。搜索中用到的是目标函数值的信息,可以不必用到目标函数的导数信息或与具体问题有关的特殊知识。因而进化算法具有广泛的应用性,高度的非线性,易修改性和可并行性。
此外,算法本身也可以采用动态自适应技术,在进化过程中自动调整算法控制参数和编码精度,比如使用模糊自适应法 。 进化策略(ES)是在1965年由Rechenberg和Schwefel独立提出的。
进化策略的一般算法
(1) 问题为寻找实值n维矢量x,使得函数F(x): R→R取极值。不失一般性,设此程序为极小化过程。
(2) 从各维的可行范围内随机选取亲本xi,i = 1, … , p的始值。初始试验的分布一般是均匀分布。
(3) 通过对于x的每个分量增加零均值和预先选定的标准差的高斯随机变量,从每个亲本xi产生子代xi’。
(4) 通过将适应度F(xi)和F(xi’),i=1,…,P进行排序,选择并决定那些矢量保留。具有最小适应度的P个矢量变成下一代的新亲本。
进行新试验,选择具有最小方差的新子代,一直到获得充分解,或者直到满足某个终止条件。
在这个模型中,把试验解的分量看做个体的行为特性,而不是沿染色体排列的基因。假设不管发生什么遗传变换,所造成各个个体行为的变化均遵循零均值和某个标准差的高斯分布。
由于基因多效性和多基因性,特定基因的改变可以影响许多表现型特征。所以在创造新子系时,较为合适的是同时改变亲本所有分量。
(1+1)—ES:
早期的进化策略的种群中只包含一个个体,并且只使用变异操作。在每一代中,变异后的个体与其父代进行比较,并选择较好的一个,这种选择策略被称为(1+1)策略。
(1+1)—ES的缺点:
(1) 各维取定常的标推差使得程序收敛到最优解的速度很慢;
(2) 点到点搜索的脆弱本质使得程序在局部极值附近容易受停滞的影响(虽然此算法表明可以渐近地收敛到全局最优点)。
(μ+λ)—ES:μ个亲本制造λ个子代,所有解均参加生存竞争,选出最好的μ个作为下一代的亲本。
(μ,λ)—ES:只有λ个子代参加生存竞争,在每代中μ个亲本被完全取代。
1.个体的表示法:
每个解矢量不仅包括了n维试验矢量x,而且还包括了扰动矢量σ,后者给出如何变异x以及它本身如何变异的指令。
2.变异:
设x为当前矢量。σ为对应于x每个维的方差矢量,于是新的解矢量x’,σ’可以这样产生:
3.交叉:
4.选择
在进化策略中,选择是按完全确定的方式进行。(μ,λ)—ES是从λ个子代个体集中选择μ(1<μ<λA=个最好的个体;(μ+λ)—ES是从父代和子代个体的并集中选择μ个最好的个体。虽然(μ+λ)—ES保留最优的个体能保证性能单调提高,但这种策略不能处理变化的环境,因此,目前选用最多的还是(μ,λ)—ES。 进化规划(EP)由Fogel在20世纪60年代提出。
1.表示法和适应值度量
进化规划假设—个有界子空间 ,其中ui<vi。搜索区域被扩展到I=R,即个体为目标变量向量,a=x∈I,进化规划把目标函数值通过比例变换到正值,同时加入某个随机改变θ来得到适应值 ,其中δ是比例函数。
2.变异
可简化为:
3.选择
在P个父代个体每个经过一次变异产生P个子代后,进化规划利用一种随机q竞争选择方法从父代和子代的集合中选择P个个体,其中q>1是选择算法的参数。
㈤ ES原理之选主流程
分布式系统的集群方式大致可以分为主从模式(Master-Slave)和无主模式。
常用的选举算法有比较简单的Bully算法和复杂而强大的Paxos算法。
每个节点有一个唯一ID,然后对集群中所有的节点ID进行排序,选取其中最小的ID所属的节点作为Master。
Bully算法的问题: 假设当前Master因为负载过重而假死,然后ID第二大的被选举为新的Master,这时旧的Master恢复然后又被选举为Master然后又会因为负载过重而假死......
Paxos实现起来非常复杂,但非常强大,尤其在什么时机,以及如何进行选举方面的灵活性比简单的Bully算法有很大的优势,因为在现实生活中,存在比网络链接异常更多的故障模式。
ES使用的是Bully算法,并对其做了一些优化:
㈥ es查询数据的工作原理是什么
查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局唯一的id,doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id。
我们可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询
1)客户端发送请求到任意一个node,成为coordinate node(协调结点)
2)coordinate node进行hash后对document进行路由,将请求转发到对应的node,此时会使用round-robin 随机轮询算法 ,在primary shard以及其所有replica node中 随机选择一个 ,让读请求负载均衡
3)接收请求的node返回document给coordinate node
4)coordinate node返回document给客户端
es最强大的是做全文检索,就是比如你有三条数据
java真好玩儿啊
java好难学啊
j2ee特别牛
你根据java关键词来搜索,将包含java的document给搜索出来
es就会给你返回:java真好玩儿啊,java好难学啊
1)客户端发送请求到一个coordinate node
2)协调节点 将搜索请求转发到 所有的shard 对应的primary shard或replica shard
3)query phase: 每个shard将自己的搜索结果 (其实就是一些 doc id ), 返回给协调节点 ,由协调节点进行数据的 合并、排序、分页 等操作,产出最终结果
4)fetch phase:接着由 协调节点,根据doc id去各个节点上拉取实际的document数据 ,最终返回给客户端
尤其要注意的这里是先拿的id哟
㈦ es使用与原理2 -- scoll技术,bouncing results,零停机重建索引等等
默认情况下,是按照_score降序排序的,我们也可以定制排序规则
Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法
Term frequency(TF): 搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关
如:搜索请求:hello world
doc1:hello you, and world is very good
doc2:hello, how are you
doc1 肯定比doc2的评分高,因为hello world都在doc1中出现了。
Inverse document frequency(IDF): 搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,就越不相关
搜索请求:hello world
doc1:hello, today is very good
doc2:hi world, how are you
比如说,在index中有1万条document,hello这个单词在所有的document中,一共出现了1000次;world这个单词在所有的document中,一共出现了100次
那最终的结果肯定是 word的得分所占比更高
关于_score,ES还有一条规则。
Field-length norm:field长度,field越长,相关度越弱
搜索请求:hello world
doc1:{ "title": "hello article", "content": "babaaba 1万个单词" }
doc2:{ "title": "my article", "content": "blablabala 1万个单词,hi world" }
hello world在整个index中出现的次数是一样多的。最终 doc1得分更高
搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是doc values,doc values 也可以供排序,聚合,过滤等操作使用。doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上
正排索引如下:
倒排索引不可变的好处
想象一下有两个文档有同样值的时间戳字段,搜索结果用 timestamp 字段来排序。 由于搜索请求是在所有有效的分片副本间轮询的,那就有可能发生主分片处理请求时,这两个文档是一种顺序, 而副本分片处理请求时又是另一种顺序。
这就是所谓的 bouncing results 问题: 每次用户刷新页面,搜索结果表现是不同的顺序。 让同一个用户始终使用同一个分片,这样可以避免这种问题, 可以设置 preference 参数为一个特定的任意值比如用户会话ID来解决。
如
如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完。
scoll,看起来挺像分页的,但是其实使用场景不一样。分页主要是用来一页一页搜索,给用户看的;scoll主要是用来一批一批检索数据,让系统进行处理的
使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来
scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的
采用基于_doc进行排序的方式,性能较高
每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了
获得的结果会有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id
1 创建索引
2 修改索引
3 删除索引
lucene是没有type的概念的,在document中,实际上将type作为一个document的field来存储,即_type,es通过_type来进行type的过滤和筛选
一个index中的多个type,实际上是放在一起存储的,因此一个index下,不能有多个type重名,而类型或者其他设置不同的,因为那样是无法处理的
比如
底层存储是这样的
将类似结构的type放在一个index下,这些type应该有多个field是相同的
假如说,你将两个type的field完全不同,放在一个index下,那么就每条数据都d会有大量field在底层的lucene中是空值,会有严重的性能问题
1、定制dynamic策略
true:遇到陌生字段,就进行dynamic mapping
false:遇到陌生字段,就忽略
strict:遇到陌生字段,就报错
2、定制自己的dynamic mapping template(type level)
上面的设置是/my_index/my_type 的字段,如果是以_en结尾的,那么就自动映射为string类型
一个field的设置是不能被修改的,如果要修改一个Field,那么应该重新按照新的mapping,建立一个index,然后将数据批量查询出来,重新用bulk api写入index中。
批量查询的时候,建议采用scroll api,并且采用多线程并发的方式来reindex数据,每次scoll就查询指定日期的一段数据,交给一个线程即可。
(1)一开始,依靠dynamic mapping,插入数据,但是不小心有些数据是2017-01-01这种日期格式的,所以title这种field被自动映射为了date类型,实际上业务认为它应该是string类型的
(2)当后期向索引中加入string类型的title值的时候,就会报错
(3)如果此时想修改title的类型,是不可能的
(4)此时,唯一的办法,就是进行reindex,也就是说,重新建立一个索引,将旧索引的数据查询出来,再导入新索引
(5)如果说旧索引的名字,是old_index,新索引的名字是new_index,终端java应用,已经在使用old_index在操作了,难道还要去停止java应用,修改使用的index为new_index,才重新启动java应用吗?这个过程中,就会导致java应用停机,可用性降低
(6)所以说,给java应用一个别名,这个别名是指向旧索引的,java应用先用着,java应用先用goods_index alias来操作,此时实际指向的是旧的my_index
(7)新建一个index,调整其title的类型为string
(8)使用scroll api将数据批量查询出来
(9)采用bulk api将scoll查出来的一批数据,批量写入新索引
(10)反复循环8~9,查询一批又一批的数据出来,采取bulk api将每一批数据批量写入新索引
(11)将goods_index alias切换到my_index_new上去,java应用会直接通过index别名使用新的索引中的数据,java应用程序不需要停机,零提交,高可用
(12)直接通过goods_index别名来查询,是否ok
现有流程的问题,每次都必须等待fsync将segment刷入磁盘,才能将segment打开供search使用,这样的话,从一个document写入,到它可以被搜索,可能会超过1分钟!!!这就不是近实时的搜索了!!!主要瓶颈在于fsync实际发生磁盘IO写数据进磁盘,是很耗时的。