久久精品无码砖区,亚洲每日更新在线国产精品原创巨作AV,国产99视频精品免费视频6,久久精品影视免费观看

<i id="lznb9"><strike id="lznb9"><strong id="lznb9"></strong></strike></i>

<u id="lznb9"></u>
<video id="lznb9"></video>
  • <wbr id="lznb9"><ins id="lznb9"></ins></wbr> <u id="lznb9"><bdo id="lznb9"></bdo></u>

    <u id="lznb9"></u>
      <wbr id="lznb9"><center id="lznb9"></center></wbr>

      湖北企業(yè)新聞網(wǎng),歡迎您!

      幫助中心 廣告聯(lián)系

      網(wǎng)站關(guān)鍵詞: 湖北企業(yè)新聞網(wǎng)

      Elasticsearch實(shí)戰(zhàn) | 如何從數(shù)千萬手機(jī)號(hào)中識(shí)別出情侶號(hào)?

      來源:時(shí)間:2020-07-20 04:42:01 閱讀:-

      1、問題描述

      您好,請教個(gè)問題。我現(xiàn)在有2千多萬的手機(jī)號(hào)碼信息保存在es里。5個(gè)分片,3個(gè)節(jié)點(diǎn)。

      現(xiàn)在的需求是將后八位相同的號(hào)碼匹配到一起,重新放到一個(gè)index里。組成情侶號(hào)。方便后續(xù)查詢情侶號(hào)列表。

      我目前的做法是用scroll查詢出一萬條,多線程循環(huán)一萬條中的每條,去全庫掃描---但是這種做法一分鐘才能處理一萬條。您有什么新的思路沒。

      死磕Elasticsearch知識(shí)星球 https://t.zsxq.com/Iie66qV

      問題補(bǔ)充:索引存儲(chǔ)了手機(jī)號(hào),同時(shí)存儲(chǔ)了插入時(shí)間。

      2、問題分析

      2.1 情侶號(hào)的定義

      后八位相同的號(hào)碼即為情侶號(hào)。

      舉例:

      13011112222
      13511112222
      13711112222

      2.2 如何對(duì)后8位建立索引,以方便后續(xù)的識(shí)別?

      方案一 不單獨(dú)建索引,用script來實(shí)現(xiàn)

      缺點(diǎn):script效率低一些

      方案二:寫入數(shù)據(jù)的時(shí)候,同時(shí)基于后八位創(chuàng)建新的字段。

      2.3 8位相同的號(hào)碼匹配到一起,重新放到一個(gè)index里怎么實(shí)現(xiàn)?

      Elasticsearch自帶reindex功能就是實(shí)現(xiàn)索引遷移的,當(dāng)然自定義讀寫也可以實(shí)現(xiàn)。

      方案一:遍歷方式+寫入。

      • 步驟 1:基于時(shí)間遞增循環(huán)遍歷,以起始的手機(jī)號(hào)為種子數(shù)據(jù),滿足后八位相同的加上標(biāo)記flag=1。

      • 步驟 2:循環(huán)步驟1,滿足flag=1直接跳過,直到所有手機(jī)號(hào)遍歷一遍。

      • 步驟 3:將包含flag=1的字段,reindex到情侶號(hào)索引。

      方案二:聚合出情侶號(hào)組,將聚合結(jié)果reindex到情侶號(hào)索引。

      考慮到數(shù)據(jù)量級(jí)千萬級(jí)別,全量聚合不現(xiàn)實(shí)。

      可以,基于時(shí)間切片,取出最小時(shí)間戳、最大時(shí)間戳,根據(jù)數(shù)據(jù)總量和時(shí)間范圍劃分出時(shí)間間隔。

      舉例:以30分鐘為單位切割千萬級(jí)數(shù)據(jù)。

      Elasticsearch實(shí)戰(zhàn) | 如何從數(shù)千萬手機(jī)號(hào)中識(shí)別出情侶號(hào)?
      • 步驟 1:terms聚合后8位手機(jī)號(hào)。

      terms聚合只返回對(duì)應(yīng):key,value值,默認(rèn)value值由高到低排序。

      key:代表手機(jī)號(hào)后8位,value:代表相同后8位的數(shù)據(jù)量。

      • 步驟 2:top_hits子聚合取出手機(jī)號(hào)詳情。

      • 步驟 3:json解析識(shí)別出步驟2的所有手機(jī)號(hào)或_id。

      • 步驟 4:reindex步驟3的_id數(shù)據(jù)到情侶號(hào)索引。

      • 步驟 5:時(shí)間切片周期遞增,直到所有數(shù)據(jù)遍歷完畢。

      2.4 擴(kuò)展自問:手機(jī)號(hào)怎么存,才能查出來后8位?

      舉例:查詢“11112222”,返回2.1列表的三個(gè)手機(jī)號(hào)。

      • 方案1:wildcard模糊匹配。

      優(yōu)點(diǎn):無需額外字段存儲(chǔ)。

      缺點(diǎn):效率低。

      • 方案2:ngram分詞+match_phrase處理。

      優(yōu)點(diǎn):效率高。

      缺點(diǎn):需要獨(dú)立存儲(chǔ)的后8位字段。

      3、實(shí)戰(zhàn)一把

      3.1 數(shù)據(jù)建模

      3.1.1 字段設(shè)計(jì)

      只包含非業(yè)務(wù)的有效必要字段。

      (1)插入時(shí)間戳字段 insert_time, date類型。

      由:ingest默認(rèn)生成,不手動(dòng)添加,提高效率。

      (2)手機(jī)號(hào)字段 phone_number, text和keyword類型。

      • text類型基于ngram分詞,主要方便phone_number全文檢索。

      • keyword類型方便:排序和聚合使用。

      (3)后8位手機(jī)號(hào)字段 last_eight_number, keyword類型。

      只聚合和排序用,不檢索。

      3.1.2 ingest處理初始化數(shù)據(jù)先行

      ingest pipeline的核心功能可以理解為寫入前數(shù)據(jù)的ETL。

      而:insert_time可以自動(dòng)生成、last_eight_number可以基于phone_number提取。

      定義如下:

      # 0.create ingest_pipeline of insert_time and last_eight_number
      PUT _ingest/pipeline/initialize
      {
      "description": "Adds insert_time timestamp to documents",
      "processors": [
      {
      "set": {
      "field": "_source.insert_time",
      "value": "{{_ingest.timestamp}}"
      }
      },
      {
      "script": {
      "lang": "painless",
      "source": "ctx.last_eight_number = (ctx.phone_number.substring(3,11))"
      }
      }
      ]
      }

      3.1.3 模板定義

      兩個(gè)索引:

      • 索引1:phone_index,存儲(chǔ)全部手機(jī)號(hào)(數(shù)千萬)

      • 索引2:phone_couple_index,存儲(chǔ)情侶號(hào)

      由于兩索引Mapping結(jié)構(gòu)一樣,使用模板管理會(huì)更為方便。

      定義如下:

      # 1.create template of phone_index and phone_couple_index
      PUT _template/phone_template
      {
      "index_patterns": "phone_*",
      "settings": {
      "number_of_replicas": 0,
      "index.default_pipeline": "initialize",
      "index": {
      "max_ngram_diff": "13",
      "analysis": {
      "analyzer": {
      "ngram_analyzer": {
      "tokenizer": "ngram_tokenizer"
      }
      },
      "tokenizer": {
      "ngram_tokenizer": {
      "token_chars": [
      "letter",
      "digit"
      ],
      "min_gram": "1",
      "type": "ngram",
      "max_gram": "11"
      }
      }
      }
      }
      },
      "mappings": {
      "properties": {
      "insert_time":{
      "type":"date"
      },
      "last_eight_number":{
      "type":"keyword"
      },
      "phone_number": {
      "type": "text",
      "fields": {
      "keyword": {
      "type": "keyword"
      }
      },
      "analyzer": "ngram_analyzer"
      }
      }
      }
      }

      3.1.4 索引定義

      PUT phone_index
      PUT phone_couple_index

      3.2 數(shù)據(jù)寫入

      采用模擬數(shù)據(jù),實(shí)際業(yè)務(wù)會(huì)有所區(qū)別。

      POST phone_index/_bulk
      {"index":{"_id":1}}
      {"phone_number" : "13511112222"}
      {"index":{"_id":2}}
      {"phone_number" : "13611112222"}
      {"index":{"_id":3}}
      {"phone_number" : "13711112222"}
      {"index":{"_id":4}}
      {"phone_number" : "13811112222"}
      {"index":{"_id":5}}
      {"phone_number" : "13844248474"}
      {"index":{"_id":6}}
      {"phone_number" : "13866113333"}
      {"index":{"_id":7}}
      {"phone_number" : "15766113333"}

      模擬數(shù)據(jù)顯示,有兩組情侶號(hào)。

      • 第一組情侶號(hào)尾數(shù):“11112222”

      • 第二組情侶號(hào)尾數(shù):“66113333”

      3.2 數(shù)據(jù)聚合

      如前所述,聚合的目的是:提取出情侶號(hào)(>=2)的手機(jī)號(hào)或?qū)?yīng)id。

      GET phone_index/_search
      {
      "size": 0,
      "query": {
      "range": {
      "insert_time": {
      "gte": 1584871200000,
      "lte": 1584892800000
      }
      }
      },
      "aggs": {
      "last_aggs": {
      "terms": {
      "field": "last_eight_number",
      "min_doc_count": 2,
      "size": 10,
      "shard_size": 30
      },
      "aggs": {
      "sub_top_hits_aggs": {
      "top_hits": {
      "size": 100,
      "_source": {
      "includes": "phone_number"
      },
      "sort": [
      {
      "phone_number.keyword": {
      "order": "asc"
      }
      }
      ]
      }
      }
      }
      }
      }
      }

      注意:

      • 查詢的目的:按時(shí)間間隔取數(shù)據(jù)。原因:「聚合全量性能太差」。

      • 外層聚合last_aggs統(tǒng)計(jì):情侶號(hào)分組及數(shù)量。

      • 內(nèi)層子聚合sub_top_hits_aggs統(tǒng)計(jì):下鉆的手機(jī)號(hào)或_id等信息。

      • min_doc_count作用:聚合后的分組記錄最小條數(shù),情侶號(hào)必須>=2,則設(shè)置為2。

      3.4 數(shù)據(jù)遷移

      基于3.3 取出的滿足條件的id進(jìn)行跨索引遷移。

      POST _reindex
      {
      "source": {
      "index": "phone_index",
      "query": {
      "terms": {
      "_id": [
      1,
      2,
      3,
      4,
      6,
      7
      ]
      }
      }
      },
      "dest": {
      "index": "phone_couple_index"
      }
      }

      注意:實(shí)際業(yè)務(wù)需要考慮數(shù)據(jù)規(guī)模,劃定輪詢時(shí)間間隔區(qū)間。

      建議:按照2.3章節(jié)的流程圖執(zhí)行。

      4、方案進(jìn)一步探究

      第3節(jié)的實(shí)戰(zhàn)一把實(shí)際是基于基礎(chǔ)數(shù)據(jù)都寫入ES了再做的處理。

      核心的操作都是基于Elasticsearch完成的。

      試想一下,這個(gè)環(huán)節(jié)如果提前是不是更合理呢?

      數(shù)據(jù)圖如下所示:

      Elasticsearch實(shí)戰(zhàn) | 如何從數(shù)千萬手機(jī)號(hào)中識(shí)別出情侶號(hào)?
      • 電話數(shù)據(jù)信息寫入消息隊(duì)列(如:kafka、rocketmq、rabbitmq等)。

      • 消息隊(duì)列可以直接同步到ES的phone_index索引。如:紅線所示。

      • 情侶號(hào)的處理借助第三方redis服務(wù)實(shí)現(xiàn),逐條過濾,滿足條件的數(shù)據(jù)同步到ES的情侶號(hào)索引phone_couple_index。如:綠線所示。

      這樣,Elasticsearch只干它最擅長的事情,剩下的工作前置交給消息隊(duì)列完成。

      5、小結(jié)

      本文就提出問題做了詳細(xì)的闡述和實(shí)踐,用到Elasticsearch 模板、Ingest、reindex等核心知識(shí)點(diǎn)和操作,給線上業(yè)務(wù)提供了理論參考。

      大家對(duì)本文有異議或者有更好的方案,歡迎留言交流。

      推薦閱讀:山東熱線