精华内容
下载资源
问答
  • 1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)2)coordinating node,document进行路由,将请求转发给对应的node(有primary shard)3)实际的node上的primary shard处理请求,...

    一、Elasticsearch写人数据的过程

    1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)
    2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)
    3)实际的node上的primary shard处理请求,然后将数据同步到replica node
    4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

     

    二、Elasticsearch读取数据的过程

    1)客户端发送请求到任意一个node,成为coordinate node
    2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡
    3)接收请求的node返回document给coordinate node
    4)coordinate node返回document给客户端

    1.写入document时,每个document会自动分配一个全局唯一的id即doc id,同时也是根据doc id进行hash路由到对应的primary shard上。也可以手动指定doc id,比如用订单id,用户id。
    
    2.读取document时,你可以通过doc id来查询,然后会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询

     

    三、Elasticsearch搜索数据过程

    es最强大的是做全文检索

    1)客户端发送请求到一个coordinate node
    2)协调节点将搜索请求转发到所有的shard对应的primary shard或replica shard也可以
    3)query phase:每个shard将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果
    4)fetch phase:接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端

    搜索的底层原理:倒排索引

     

    四、Elasticsearch写数据的底层原理

    1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件。

    2)如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。

    每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据。

    但是如果buffer里面此时没有数据,那当然不会执行refresh操作咯,每秒创建换一个空的segment file,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中。

    操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去。

    只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了。

    为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。

    可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。

    只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了。

     

      

    转载于:https://www.cnblogs.com/756623607-zhang/p/10598043.html

    展开全文
  • 1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点) 2)coordinating node,document进行路由,将请求转发给对应的node(有primary shard) 3)实际的node上的primary shard处理...

    分布式搜索引擎的面试连环炮

    面试题

    es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?

    面试官心理分析

    问这个,其实面试官就是要看看你了解不了解 es 的一些基本原理,因为用 es 无非就是写入数据,搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es 在干什么,那你真的是......

    对 es 基本就是个黑盒,你还能干啥?你唯一能干的就是用 es 的 api 读写数据了。要是出点什么问题,你啥都不知道,那还能指望你什么呢?

    面试题剖析

    01_es读写底层原理剖析

    1.es写数据过程

    1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)

    2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)

    3)实际的node上的primary shard处理请求,然后将数据同步到replica node

    4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

    5)写数据底层原理

    1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件

    2)如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。

    每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据

    但是如果buffer里面此时没有数据,那当然不会执行refresh操作咯,每秒创建换一个空的segment file,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中

    操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去

    只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了

    为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。

    可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。

    只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份

    3)只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了

    4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。

    buffer中的数据,倒是好,每隔1秒就被刷到os cache中去,然后这个buffer就被清空了。所以说这个buffer的数据始终是可以保持住不会填满es进程的内存的。

    每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的,当translog日志文件大到一定程度的时候,就会执行commit操作。

    5)commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer

    6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的所有segment file

    7)强行将os cache中目前所有的数据都fsync到磁盘文件中去

    translog日志文件的作用是什么?就是在你执行commit操作之前,数据要么是停留在buffer中,要么是停留在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。

    所以需要将数据对应的操作写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。

    commit操作:1、写commit point;2、将os cache数据fsync强刷到磁盘上去;3、清空translog日志文件

    8)将现有的translog清空,然后再次重启启用一个translog,此时commit操作完成。默认每隔30分钟会自动执行一次commit,但是如果translog过大,也会触发commit。整个commit的过程,叫做flush操作。我们可以手动执行flush操作就是将所有os cache数据刷到磁盘文件中去。

    不叫做commit操作,flush操作。es中的flush操作,就对应着commit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

    9)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。

    实际上你在这里,如果面试官没有问你es丢数据的问题,你可以在这里给面试官炫一把,你说,其实es第一是准实时的,数据写入1秒后可以搜索到;可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时如果宕机,会导致5秒的数据丢失。

    如果你希望一定不能丢失数据的话,你可以设置个参数,官方文档,百度一下。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。

    10)如果是删除操作,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了

    11)如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据

    12)buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

    13)每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。

    es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge

    当segment file多到一定程度的时候,es就会自动触发merge操作,将多个segment file给merge成一个segment file(大),合并的过程中会读取.del文件,进行物理删除。

    2.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对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡

    3)接收请求的node返回document给coordinate node

    4)coordinate node返回document给客户端

    3.es搜索数据过程

    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数据,最终返回给客户端

    5)搜索的底层原理,倒排索引,画图说明传统数据库和倒排索引的区别

     

    展开全文
  • 动网论坛作搜索引擎优化

    千次阅读 2005-03-26 10:42:00
    作者:david本文地址:...动网论坛采用javascript+模版的方式显示页面,服务器将没有深加工的数据和js代码一起发送到客户端解析,减轻了服务器负担,但是搜索引擎一般不会解

    作者:david

    本文地址:http://blog.iyi.cn/user/david/archives/2005/03/261.html

    今天对 车米网 的论坛作了优化,发现动网论坛7.0本来就考虑到了搜索引擎的问题,只需要简单修改就可以很好的优化了.

    动网论坛采用javascript+模版的方式显示页面,服务器将没有深加工的数据和js代码一起发送到客户端解析,减轻了服务器负担,但是搜索引擎一般不会解析javascript代码的,不过动网论坛的主要页面都有判断浏览器类型,如果是搜索引擎,自动跳转到专门为浏览器显示的页面,但是这些页面做得不是太好,下面是我修改的结果:

    昨天我把论坛的meta标签的description部分去掉,google发现这个标签后就会忽略下面的内容,直接区标签中的内容。

    修改index.asp:

          将函数Sub Show_Index_Footer()中的

    Dim BrowserType

    If BrowserType.IsSearch Then Response.redirect "indexNew.asp"

    提升到index.asp的前面,让页面一检测到是搜索引擎就跳转到优化后的页面,原来那样子的结果是google仅仅抓取了Show_Index_Footer()中的信息,前面的都给忽略了。

    修改indexnew.asp

    将Dvbbs.head()改为Dvbbs.head()

    注释掉

    Dvbbs.ActiveOnline()

    Show_Index_Top

    Show_Index_Footer

    Response.Write Replace(template.html(9),"{$Getlink}",Getlink())

    If Dvbbs.Forum_setting(29)="1" Then Call birthuser()

    Dvbbs.Footer()

    Response.Write Dvbbs.value

    Response.Write template.html(8)(1)

    这样子跳转后的首页显示的就相对比较简单了,但是代码还是有些冗余,如果想再精简些,就不要用dvbbs的模版了,直接用asp生成静态页面,能去掉的都去掉。

    同样修改list_show.asp

    将Dvbbs.head()改为Dvbbs.head()

    注释掉

    News

    Board_Online

    Show_List_Footer

    Dvbbs.ActiveOnline()

    Dvbbs.Footer()

    再修改printpage.asp

    如果你的论坛需要注册用户才能浏览,而你又要搜索引擎能够抓取信息的话,把If Dvbbs.GroupSetting(2)="0"  Then Dvbbs.AddErrcode(31)这行注释掉。

    其他的没什么好改的,这个页面的模版已经做得非常精简了,你可以试着修改page_postjob模版来增加些其他的连接。

    下面作一个更有实际效果的索引页面,很多不错的php论坛都有这样的页面,效果很好:

    新建一个目录,随便什么,然后在里面建立一个index.asp文件,这个文件的代码我直接用了动网论坛的newtopic.asp,把里面的js去掉就行了:

    <!--#include file="../conn.asp"-->
    <!--#Include File="../inc/Dv_ClsMain.asp"-->
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

    <title>车米网</title>
    <link rel="stylesheet" href="../style.css" type="text/css" />
    </head>
    <body>
    <div class="main">
    <div class="top"><a href="../index.asp">车米网</a> - 论坛新贴</div>
    <div class="body">
    <%
    'DVBBS 7.0 动网论坛首页调用-----主题调用
    dim bbsurl,lockboardid,picurl
    '############以下为修改项######################
    dim lockurl
    lockurl=""
    '只允许调用网址,要以"HTTP://"开头,为空则不开放此功能.(可允许多网址限制,要以","分隔。)
    '例如只允许此两个网址调用: lockurl="http://www.artistsky.net/,http://www.artbbs.net/"
    bbsurl="http://bbs.my-car.cn/"       '请填写你论坛的正确地址,要以"HTTP://"开头
    lockboardid="1,2,3"          '请填写限制调用的论坛版块ID,用逗号隔开。(当lock参数为1,2时生效)
    picurl="http://bbs.my-car.cn/skins/default/topicface/" '心情图标目录地址
    '############以上为修改项######################
    'bbsurl=getservepath(request.ServerVariables("server_name")&request.ServerVariables("URL"))
    'function getservepath(str)
    'dim tmpstr
    'tmpstr=split(str,"/")
    'getservepath="http://"&replace(str, tmpstr(ubound(tmpstr)), "")
    'end function
    '*************************************
    '上传到与CONN.ASP同级的目录下
    '以上地址参数一定要修改,否则所调用的链接是去了以上的论坛.
    '若有问题,可以运行一起上传的newscode.ASP文件进行调试(newscode.ASP运行前要修改调用参数)
    ' FSSUNWIN 2003.12.31
    '*************************************
    'if trim(lockurl)<>"" and checkserver(lockurl)=false then
    ' response.write "document.write ('数据被保护,禁止被其他站点调用!"
    ' response.end 
    'end if

    Private function checkserver(str)
     dim i,servername
     checkserver=false
     if str="" then exit function
     str=split(Cstr(str),",")
     servername=Request.ServerVariables("HTTP_REFERER")
     for i=0 to Ubound(str)
     if right(str(i),1)="/" then str(i)=left(trim(str(i)),len(str(i))-1)
      if Lcase(left(servername,len(str(i))))=Lcase(str(i)) then
       checkserver=true
       exit for
      else
       checkserver=false
      end if
     next
    end function

    dim rs,sql
    dim orders,reply,topic,isbest,lock,board,action,info,tlen,showpic
    dim bname,ars
    dim postinfo,postname,POSTTIME
    dim NowUseBbs,boardname,boardid
    dim i,k,n,sdate,searchdate
     i=0:k=0
     lock=0  'cint(trim(request("lock")))
     orders=4 'trim(request("orders"))
     boardid="all" 'trim(request("boardid"))
     sdate=3 'trim(request("sdate"))
     action=1 'cint(request("action"))
     info=3  'request("info")
     tlen=16  'request("tlen")
     reply=0  'request("reply")
     showpic=0 'request("showpic")
     n=100  'trim(request("n"))
     bname=0  'request("bname")
     if n<>"" and IsNumeric(n) then
     n=cint(n)
     else
     n=1
     end if

     if orders=1 then
      orders="hits desc,"
     Elseif orders=2 or orders=3 then
      orders="dateandtime desc,"
     end if
     If boardid<>"all" and isnumeric(boardid) then
      if boardid=444 then
      response.write "document.write ('错误的版块参数,调用被中止!"
      response.end
      Else
      board=" and BoardID="&cint(boardid)
      if lock=3 then board=" and BoardID in (select boardid from board where ParentID="&cint(boardid)&") "
      End If
     End If
     
     if lock=1 then
      board=" and boardid not in ("&lockboardid&") "
     elseif lock=2 then
      board=" and boardid in ("&lockboardid&") "
     end if

     Dvbbs.GetForum_Setting
     connectionDatabase
     if sdate<>"" and IsNumeric(sdate) then
      sdate=cint(sdate)
      if IsSqlDataBase=1 Then
      searchdate=" and datediff(day,dateandtime,"&SqlNowString&")<"&sdate
      else
      searchdate=" and datediff('d',dateandtime,"&SqlNowString&")<"&sdate
      end if
     else
     searchdate=""
     end if

     if action=1 then
      '显示主题
      if orders=2 then orders="lastposttime,"
      if orders=4 then orders=""
      set rs=conn.execute("select top "&n&" PostUserName,Title,topicid,boardid,dateandtime,topicid,hits,Expression,LastPost from Dv_topic where boardid<>444 "&board&searchdate&" ORDER BY "&orders&" topicid desc")
     elseif action=2 then
      '显示精华主题
      if searchdate<>"" then searchdate=replace(searchdate," and"," where")
      if searchdate="" and board<>"" then board=replace(board," and"," where")
      set rs=conn.execute("select top "&n&" PostUserName,Title,rootid,boardid,dateandtime,Announceid,id,Expression from Dv_BestTopic  "&board&searchdate&"  ORDER BY "&orders&" id desc")
        else
         '显示主题或回复
      set rs=conn.execute("select top "&n&" username,topic,rootid,boardid,dateandtime,announceid,body,Expression from "&Dvbbs.NowUseBBS&" where (not boardid=444) "&board&searchdate&" ORDER BY "&orders&" AnnounceID desc")
     end if
     If Not RS.Eof then
      SQL=Rs.GetRows(-1)
      else
      response.write "暂未有新帖子!"
      response.end
        end if
        rs.close
     set rs=nothing

     For i=0 To Ubound(SQL,2)
      topic=SQL(1,i)
      if topic="" then
       topic=SQL(6,i)
      end if
      Topic=Stringhtml(topic)
      if len(topic)>Cint(tlen) then
       topic=left(topic,tlen)&"..."
      end if
      
      postname=SQL(0,i)
      POSTTIME=SQL(4,i)
      if action=1 and reply=1 then
       if SQL(8,i)<>"" then
       postinfo=split(SQL(8,i),"$")
       postname=postinfo(0)
       POSTTIME=postinfo(2)
       end if
      end if
      response.write "<li class=list>"
      if showpic=1 then
      response.write "<IMG SRC="""&picurl&SQL(7,i)&""" BORDER=0 >"
      else
      end if
      if bname=1 then
       set ars=conn.execute("select BoardType from Dv_board where boardid="&SQL(3,i))
        boardname=ars(0)
        ars.close
        response.write "[<a href="&bbsurl&"list.asp?boardid="&SQL(3,i)&" target=""_blank"">"&Dvbbs.htmlencode(boardname)&"</a>] "
      end if
      response.write "<a href="&bbsurl&"printpage.asp?boardid="&SQL(3,i)&"&ID="&SQL(2,i)&"&replyID="&SQL(5,i)&" target=""_blank"" title="&Topic&">"
      response.write ""&Topic&""
      response.write "</a>"
      select case cint(info)
      case 0
      case 1
      response.write "(<a href="&bbsurl&"dispuser.asp?name="&postname&" target=_blank>"&postname&"</a>,<font color=green>"&formatdatetime(POSTTIME,0)&"</font>)"
      case 2
      response.write "(<font color=green>"&POSTTIME&"</font>)"
      case 3
      response.write "(<a href="&bbsurl&"dispuser.asp?name="&postname&" target=_blank>"&postname&"</a>)"
      case 4
      response.write "(<a href="&bbsurl&"dispuser.asp?name="&postname&" target=_blank>"&postname&"</a>"
      if cint(action)=1 then response.write ",<font color=green>"&SQL(6,i)&"</font>"
      Response.Write ")"
      case 5
      if cint(action)=1 then
      response.write "(<font color=green>"&SQL(6,i)&"</font>)"
      end if
      case 6
      response.write "(<a href="&bbsurl&"dispuser.asp?name="&postname&" target=_blank>"&postname&"</a>,<font color=green>"&formatdatetime(POSTTIME,1)&"</font>)"
      case 7
      response.write "(<font color=green>"&formatdatetime(POSTTIME,1)&"</font>)"
      case else

      end select
      response.write "</li>"
      k=k+1
     Next
     Call CloseObject

     Sub CloseObject()
      Set template = Nothing
      Set MyBoardOnline = Nothing
      Set Dvbbs = Nothing
      Set Conn = Nothing
     End Sub

     Function Stringhtml(str)
      Dim re
      Set re=new RegExp
      re.IgnoreCase =True
      re.Global=True
      're.Pattern="<(.*)>"
      'str=re.replace(str, "")
      re.Pattern="/[(.*)/]"
      str=re.replace(str, "")
      str = Replace(str, CHR(34), """")
      str = Replace(str, CHR(39), "/'")
      str = Replace(str, CHR(13), "")
      str = Replace(str, CHR(10), "")
      str = replace(str, ">", "&gt;")
      str = replace(str, "<", "&lt;")
      if str="" then str="..."
      Stringhtml=str
     End Function
    %>
    </div>
    </div>
    </body>
    </html>

    效果见http://bbs.my-car.cn/newtopic

    然后再去修改indexnew.asp,加上这个页面的索引就行了。

    剩下的大家去挖掘吧~哈哈

    展开全文
  • 用es无非就是写入数据搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es在干什么,那你真的就是。。。。 es基本就是个黑盒,你还能干啥?你唯一能干的就是用es的api读写数据了。。。要是出点什么问题,...

    前言:本文章来着中华石杉老师视频,老师真滴棒!

    背景:
    用es无非就是写入数据,搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es在干什么,那你真的就是。。。。

    对es基本就是个黑盒,你还能干啥?你唯一能干的就是用es的api读写数据了。。。要是出点什么问题,你啥都不知道,那还能指望你什么呢?是不是。。

    (1)es写数据过程

    • 1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点);
    • 2)coordinating node,对document进行路由,将请求转发给对应的node(primary shard);
    • 3)实际的node上的primary shard处理请求,然后将数据同步到replica node
    • 4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端。

    (2)es读数据过程

    查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局唯一的iddoc 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对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法在primary shard以及其所有replica中随机选择一个,让读请求负载均衡;
    • 3)接收请求的node返回document给coordinate node;
    • 4)coordinate node返回document给客户端。

    (3)es搜索数据过程

    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数据,最终返回给客户端。

    (4)搜索的底层原理,倒排索引,画图说明传统数据库和倒排索引的区别

    (5)写数据底层原理

    1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件
    2)refresh: 如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh

    • 每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据
    • 但是如果buffer里面此时没有数据,那当然不会执行refresh操作咯,每秒创建换一个空的segment file,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中
    • 操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去
    • 只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了
    • 为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。
    • 可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。
    • 只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了

    3)只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了
    4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。

    • buffer中的数据,倒是好,每隔1秒就被刷到os cache中去,然后这个buffer就被清空了。所以说这个buffer的数据始终是可以保持住不会填满es进程的内存的。
    • 每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的,当translog日志文件大到一定程度的时候,就会执行commit操作。

    5)commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer
    6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的所有segment file
    7)强行将os cache中目前所有的数据都fsync到磁盘文件中去

    • translog日志文件的作用是什么?就是在你执行commit操作之前,数据要么是停留在buffer中,要么是停留在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。
    • 所以需要将数据对应的操作写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。
    • commit操作:1、写commit point;2、将os cache数据fsync强刷到磁盘上去;3、清空translog日志文件

    8)将现有的translog清空,然后再次重启启用一个translog,此时commit操作完成。

    • 默认每隔30分钟会自动执行一次commit,但是如果translog过大,也会触发commit。

    • 整个commit的过程,叫做flush操作。我们可以手动执行flush操作,就是将所有os
      cache数据刷到磁盘文件中去。

    • 不叫做commit操作,flush操作。**es中的flush操作,就对应着commit的全过程。**我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

    9)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。

    实际上你在这里,如果面试官没有问你es丢数据的问题,你可以在这里给面试官炫一把,你说,

    • 其实es第一是准实时的,数据写入1秒后可以搜索到;
    • 可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时如果宕机,会导致5秒的数据丢失。

    如果你希望一定不能丢失数据的话,你可以设置个参数,官方文档,百度一下。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。

    10)如果是删除操作,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了。

    11)如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据;

    12)buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

    13)每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。

    es里的写流程,有4个底层的核心概念,refresh(一秒)、flush(五秒)、translog、merge

    当segment file多到一定程度的时候,es就会自动触发merge操作,将多个segment file给merge成一个segment file。

    在这里插入图片描述

    展开全文
  • 淘特站内搜索引擎简介 淘特站内搜索引擎是一个以jsp进行开发的jsp搜索引擎源码。 系统具有以下特点: 1、支持海量数据快速查询(1000万条以上) 2、支持按关键字精确查询或模糊查询。 3、支持按时间段查询 4、...
  • 2.1搜索引擎提炼2

    2020-04-10 13:47:45
    (1)es的分布式架构原理能说一下么(es是如何实现分布式的啊)? (2)es写入数据的工作原理是什么啊?es查询数据的工作原理是什么啊... 2)coordinating node,document进行路由,将请求...
  • 美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过离线数据收集、挖掘,可目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致用户在...
  • 开源企业搜索引擎SOLR的应用教程 Apache Solr 是一个开源的搜索服务器,Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。定制 Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述...
  • 本文介绍了如何整合搜索引擎elasticsearch与springboot,对外提供数据查询接口。 业务介绍 我的个人网站需要mysql数据库内存储的京东商品进行模糊查询(模仿淘宝商品搜索),所以选择了将数据导入elasticsearch...
  • 实现很简单的搜索引擎

    千次阅读 2011-09-05 00:41:32
    简单实现了各个模块的功能,整体有了了解,当然...(1)网络爬虫模块:该模块是从URL库中获得输入,解析URL中表明的Web服务器地址,建立连接,发送请求和接受数据,将获得的网页数据存储在原始网页库中,并从其中提
  • 1)客户端选择一个node发送请求,这个node就是coordinating node(协调节点)。 2)coordinating node,document进行路由,将请求转发给对应的node(有primary shard)。 3)实际的node上的primary shard处理...
  • 背景美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过离线数据收集、挖掘,可目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致...
  • 美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过离线数据收集、挖掘,可目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致用户在...
  • 美团点评酒旅运营需求在离线场景下,已经得到了较为系统化的支持,通过离线数据收集、挖掘,可目标用户进行T+1触达,通过向目标用户发送Push等多种方式,在一定程度上提高转化率。但T+1本身的延迟性会导致用户在...
  • 前言本文介绍了如何整合搜索引擎elasticsearch与springboot,对外提供数据查询接口。业务介绍我的个人网站需要mysql数据库内存储的京东商品进行模糊查询(模仿淘宝商品搜索),所以选择了将数据导入elasticsearch...
  • 先简单说一下过程,再说原理一、ES写入数据过程1、客户端随机选择一个 node 发送请求,这个 node 就是 coordinating node(协调节点)2、coordinating node document 进行路由,将请求转发到该索引的 primary shard...
  • PageRank 算法最初提出来用于利用网页之间的链接关系来网页进行排序,从而优化搜索引擎的效果。如今,我们可以将 PageRank 算法用作网络中节点排序的一般算法。在本案例中,我们使用一个全球机场之间航线的网络...
  • 官方的帮助文档每个函数有详细介绍,大家有不懂的地方首先查看帮助文档,配合搜索引擎深化理解。     串口发送一次数据过程的可以分为三个步骤:打开串口–>发送数据–>关闭串口。分别对应Confugure Port,...
  • 官方的帮助文档每个函数有详细介绍,大家有不懂的地方首先查看帮助文档,配合搜索引擎深化理解。 串口发送一次数据过程的可以分为三个步骤:打开串口-->发送数据-->关闭串口。分别对应Confugure Port,...
  • ES数据同步方案

    千次阅读 2019-03-06 08:41:11
    当业务量上升后,由于mysql...我们可以将数据发送搜索引擎(如ES)上,由搜索引擎来提供专业的服务。 接下来,就结合工作中实际用到的场景,对数据从mysql到es的同步进行一些分析。 在实践中我总结出了以下几...
  • 以上三篇分别讲解了elasticsearch的原理介绍,...不同于SQL语言,ElasticSearch引擎发送的查询请求,有两种方式:第一种方式是使用RESTful 风格的API请求对数据进行搜索或更新,这意味着,必须使用搜索API向Ela...
  • 不同于SQL语言,ElasticSearch引擎发送的查询请求,有两种方式:第一种方式是使用RESTful 风格的API请求对数据进行搜索或更新,这意味着,必须使用搜索API向ElasticSearch引擎发起搜索请求;第二种方式是使用Qeury...
  • 我们可以将数据发送搜索引擎(如ES)上,由搜索引擎来提供专业的服务。接下来,就结合工作中实际用到的场景,对数据从mysql到es的同步进行一些分析。在实践中我总结出了以下几种方式。第1种:同步双写这是...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 276
精华内容 110
关键字:

对搜索引擎发送数据