成全视频在线观看免费高清,国产亚洲欧洲精品,成年人午夜免费视频,久久机热综合久久国产

刷卡機(jī)磁頭的原理

瀏覽:61 發(fā)布日期:2023-05-25 00:00:00 投稿人:佚名投稿

網(wǎng)上關(guān)于刷卡機(jī)磁頭的原理的刷卡知識(shí)比較多,也有關(guān)于刷卡機(jī)磁頭的原理的問題,今天第一pos網(wǎng)(www.yadikedp.com)為大家整理刷卡常見知識(shí),未來的我們終成一代卡神。

本文目錄一覽:

1、刷卡機(jī)磁頭的原理

刷卡機(jī)磁頭的原理

之前幾段工作經(jīng)歷都與搜索有關(guān),現(xiàn)在也有業(yè)務(wù)在用搜索,對(duì)搜索引擎做一個(gè)原理性的分享,包括搜索的一系列核心數(shù)據(jù)結(jié)構(gòu)和算法,盡量覆蓋搜索引擎的核心原理,但不涉及數(shù)據(jù)挖掘、NLP等。文章有點(diǎn)長(zhǎng),多多指點(diǎn)~~

一、搜索引擎引題

搜索引擎是什么?

這里有個(gè)概念需要提一下。信息檢索 (Information Retrieval 簡(jiǎn)稱 IR) 和 搜索 (Search) 是有區(qū)別的,信息檢索是一門學(xué)科,研究信息的獲取、表示、存儲(chǔ)、組織和訪問,而搜索只是信息檢索的一個(gè)分支,其他的如問答系統(tǒng)、信息抽取、信息過濾也可以是信息檢索。

本文要講的搜索引擎,是通常意義上的全文搜索引擎、垂直搜索引擎的普遍原理,比如 Google、Baidu,天貓搜索商品、口碑搜索美食、飛豬搜索酒店等。

Lucene 是非常出名且高效的全文檢索工具包,ES 和 Solr 底層都是使用的 Lucene,本文的大部分原理和算法都會(huì)以 Lucene 來舉例介紹。

為什么需要搜索引擎?

看一個(gè)實(shí)際的例子:如何從一個(gè)億級(jí)數(shù)據(jù)的商品表里,尋找名字含“秋褲”的 商品。

使用SQL Like

select * from item where name like \'%秋褲%\'

如上,大家第一能想到的實(shí)現(xiàn)是用 like,但這無法使用上索引,會(huì)在大量數(shù)據(jù)集上做一次遍歷操作,查詢會(huì)非常的慢。有沒有更簡(jiǎn)單的方法呢,可能會(huì)說能不能加個(gè)秋褲的分類或者標(biāo)簽,很好,那如果新增一個(gè)商品品類怎么辦呢?要加無數(shù)個(gè)分類和標(biāo)簽嗎?如何能更簡(jiǎn)單高效的處理全文檢索呢?

使用搜索引擎

答案是搜索,會(huì)事先 build 一個(gè)倒排索引,通過詞法語法分析、分詞、構(gòu)建詞典、構(gòu)建倒排表、壓縮優(yōu)化等操作構(gòu)建一個(gè)索引,查詢時(shí)通過詞典能快速拿到結(jié)果。這既能解決全文檢索的問題,又能解決了SQL查詢速度慢的問題。

那么,淘寶是如何在1毫秒從上億個(gè)商品找到上千種秋褲的呢,谷歌如何在1毫秒從萬億個(gè)網(wǎng)頁中找尋到與你關(guān)鍵字匹配的幾十萬個(gè)網(wǎng)頁,如此大的數(shù)據(jù)量是怎么做到毫秒返回的。

二、搜索引擎是怎么做的?

Part1. 分詞

分詞就是對(duì)一段文本,通過規(guī)則或者算法分出多個(gè)詞,每個(gè)詞作為搜索的最細(xì)粒度一個(gè)個(gè)單字或者單詞。只有分詞后有這個(gè)詞,搜索才能搜到,分詞的正確性非常重要。分詞粒度太大,搜索召回率就會(huì)偏低,分詞粒度太小,準(zhǔn)確率就會(huì)降低。如何恰到好處的分詞,是搜索引擎需要做的第一步。

正確性&粒度

分詞正確性“他說的確實(shí)在理”,這句話如何分詞?“他-說-的確-實(shí)在-理” [錯(cuò)誤語義]“他-說-的-確實(shí)-在理” [正確語義]分詞的粒度“中華人民共和國(guó)憲法”,這句話如何分詞?“中華人民共和國(guó)-憲法”,[搜索 中華、共和國(guó) 無結(jié)果]“中華-人民-共和國(guó)-憲法”,[搜索 共和 無結(jié)果]“中-華-人-民-共-和-國(guó)-憲-法”,[搜索其中任意字都有結(jié)果]

分詞的粒度并不是越小越好,他會(huì)降低準(zhǔn)確率,比如搜索 “中秋” 也會(huì)出現(xiàn)上條結(jié)果,而且粒度越小,索引詞典越大,搜索效率也會(huì)下降,后面會(huì)細(xì)說。

如何準(zhǔn)確的把控分詞,涉及到 NLP 的內(nèi)容啦,這里就不展開了。

停用詞

很多語句中的詞都是沒有意義的,比如 “的”,“在” 等副詞、謂詞,英文中的 “a”,“an”,“the”,在搜索是無任何意義的,所以在分詞構(gòu)建索引時(shí)都會(huì)去除,降低不不要的索引空間,叫停用詞 (StopWord)。

通常可以通過文檔集頻率和維護(hù)停用詞表的方式來判斷停用詞。

詞項(xiàng)處理

詞項(xiàng)處理,是指在原本的詞項(xiàng)上在做一些額外的處理,比如歸一化、詞形歸并、詞干還原等操作,以提高搜索的效果。并不是所有的需求和業(yè)務(wù)都要詞項(xiàng)處理,需要根據(jù)場(chǎng)景來判斷。

1.歸一化

USA - U.S.A. [縮寫]7月30日 - 7/30 [中英文]color - colour [通假詞]開心 - 高興 [同義詞擴(kuò)展范疇]

這樣查詢 U.S.A. 也能得到 USA 的結(jié)果,同義詞可以算作歸一化處理,不過同義詞還可以有其他的處理方式。

2.詞形歸并(Lemmatization)

針對(duì)英語同一個(gè)詞有不同的形態(tài),可以做詞形歸并成一個(gè),如:

am, are, is -> becar, cars, car\'s, cars\' -> carthe boy\'s cars are different colors -> the boy car be different color

3.詞干還原(Stemming)

通常指的就粗略的去除單詞兩端詞綴的啟發(fā)式過程

automate(s), automatic, automation -> automat.高高興興 -> 高興 [中文重疊詞還原]明明白白 -> 明白

英文的常見詞干還原算法,Porter算法。

Part2、倒排索引

要了解倒排索引,先看一下什么是正排索引。比如有下面兩句話:

id1, “搜索引擎提供檢索服務(wù)”id2, “搜索引擎是信息檢索系統(tǒng)”

正排索引

正排索引就是 MySQL 里的 B+ Tree,索引的結(jié)果是:

“搜索引擎是信息檢索系統(tǒng)” -> id2“搜索引擎提供檢索服務(wù)” -> id1

表示對(duì)完整內(nèi)容按字典序排序,得到一個(gè)有序的列表,以加快檢索的速度。

倒排索引

第一步 分詞

“搜索引擎-提供-檢索-服務(wù)” -> id1“搜索引擎-信息-檢索-系統(tǒng)” -> id2

第二步 將分詞項(xiàng)構(gòu)建一個(gè)詞典

搜索引擎提供檢索服務(wù)信息系統(tǒng)

第三步 構(gòu)建倒排鏈

搜索引擎 -> id1, id2提供 -> id1檢索 -> id1, id2服務(wù) -> id1信息 -> id2系統(tǒng) -> id2

由此,一個(gè)倒排索引就完成了,搜索 “檢索” 時(shí),得到 id1, id2,說明這兩條數(shù)據(jù)都有,搜索 “服務(wù)” 只有 id1 存在。但如果搜索 “檢索系統(tǒng)”,此時(shí)會(huì)先建搜索詞按照與構(gòu)建同一種策略分詞,得到 “檢索-系統(tǒng)”,兩個(gè)詞項(xiàng),分別搜索 檢索 -> id1, id2 和 系統(tǒng) -> id2,然后對(duì)其做一個(gè)交集,得到 id2。同理,通過求并集可以支持更復(fù)雜的查詢。

倒排索引到此也就講清楚了吧。

存儲(chǔ)結(jié)構(gòu)

以 Lucene 為例,簡(jiǎn)單說明一下 Lucene 的存儲(chǔ)結(jié)構(gòu)。從大到小是Index -> Segment -> Doc -> Field -> Term,類比 MySQL 為 Database -> Table -> Record -> Field -> Value。

Part 3、查詢結(jié)果排序

搜索結(jié)果排序是根據(jù) 關(guān)鍵字 和 Document 的相關(guān)性得分排序,通常意義下,除了可以人工的設(shè)置權(quán)重 boost,也存在一套非常有用的相關(guān)性得分算法,看完你會(huì)覺得非常有意思。

TF-IDF

TF(詞頻)-IDF(逆文檔頻率) 在自動(dòng)提取文章關(guān)鍵詞上經(jīng)常用到,通過它可以知道某個(gè)關(guān)鍵字在這篇文檔里的重要程度。其中 TF 表示某個(gè) Term 在 Document 里出現(xiàn)的頻次,越高說明越重要;DF 表示在全部 Document 里,共有多少個(gè) Document 出現(xiàn)了這個(gè)詞,DF 越大,說明這個(gè)詞很常見,并不重要,越小反而說明他越重要,IDF 是 DF 的倒數(shù)(取log), IDF 越大,表示這個(gè)詞越重要。

TF-IDF 怎么影響搜索排序,舉一個(gè)實(shí)際例子來解釋:

假定現(xiàn)在有一篇博客《Blink 實(shí)戰(zhàn)總結(jié)》,我們要統(tǒng)計(jì)這篇文章的關(guān)鍵字,首先是對(duì)文章分詞統(tǒng)計(jì)詞頻,出現(xiàn)次數(shù)最多的詞是--"的"、"是"、"在",這些是“停用詞”,基本上在所有的文章里都會(huì)出現(xiàn),他對(duì)找到結(jié)果毫無幫助,全部過濾掉。

只考慮剩下的有實(shí)際意義的詞,如果文章中詞頻數(shù)關(guān)系: “Blink” > “詞頻” = “總結(jié)”,那么肯定是 Blink 是這篇文章更重要的關(guān)鍵字。但又會(huì)遇到了另一個(gè)問題,如果發(fā)現(xiàn) "Blink"、"實(shí)戰(zhàn)"、"總結(jié)"這三個(gè)詞的出現(xiàn)次數(shù)一樣多。這是不是意味著,作為關(guān)鍵詞,它們的重要性是一樣的?

不是的,通過統(tǒng)計(jì)全部博客,你發(fā)現(xiàn) 含關(guān)鍵字總博客數(shù): “Blink” < “實(shí)戰(zhàn)” < “總結(jié)”,這時(shí)候說明 “Blink” 不怎么常見,一旦出現(xiàn),一定相比 “實(shí)戰(zhàn)” 和 “總結(jié)”,對(duì)這篇文章的重要性更大。

BM25

上面解釋了 TF 和 IDF,那么 TF 和 IDF 誰更重要呢,怎么計(jì)算最終的相關(guān)性得分呢?那就是 BM25。

BM25算法,通常用來作搜索相關(guān)性平分。一句話概況其主要思想:對(duì)Query進(jìn)行語素解析,生成語素qi;然后,對(duì)于每個(gè)搜索結(jié)果D,計(jì)算每個(gè)語素qi與D的相關(guān)性得分,最后,將qi相對(duì)于D的相關(guān)性得分進(jìn)行加權(quán)求和,從而得到Query與D的相關(guān)性得分。

BM25算法的一般性公式如下:

其中,Q表示Query,qi表示Q解析之后的一個(gè)語素(對(duì)中文而言,我們可以把對(duì)Query的分詞作為語素分析,每個(gè)詞看成語素qi。);d表示一個(gè)搜索結(jié)果文檔;Wi表示語素qi的權(quán)重;R(qi,d)表示語素qi與文檔d的相關(guān)性得分。

其中 Wi 通常使用 IDF 來表達(dá),R 使用 TF 來表達(dá);綜上,BM25算法的相關(guān)性得分公式可總結(jié)為:

BM25 通過使用不同的語素分析方法、語素權(quán)重判定方法,以及語素與文檔的相關(guān)性判定方法,我們可以衍生出不同的搜索相關(guān)性得分計(jì)算方法,這就為我們?cè)O(shè)計(jì)算法提供了較大的靈活性。

Part 4、空間索引

在點(diǎn)評(píng)口碑上,經(jīng)常有類似的場(chǎng)景,搜索 “1公里以內(nèi)的美食”,那么這個(gè)1公里怎么實(shí)現(xiàn)呢?

在數(shù)據(jù)庫中可以通過暴力計(jì)算、矩形過濾、以及B樹對(duì)經(jīng)度和維度建索引,但這性能仍然很慢(可參考 為什么需要空間索引 )。搜索里用了一個(gè)很巧妙的方法,Geo Hash。

如上圖,表示根據(jù) GeoHash 對(duì)北京幾個(gè)區(qū)域生成的字符串,有幾個(gè)特點(diǎn):

一個(gè)字符串,代表一個(gè)矩形區(qū)域字符串越長(zhǎng),表示的范圍越精確 (長(zhǎng)度為8時(shí)精度在19米左右,而當(dāng)編碼長(zhǎng)度為9時(shí)精度在2米左右)字符串相似的,表示距離相近 (這就可以利用字符串的前綴匹配來查詢附近的POI信息)Geo Hash 如何編碼?

地球上任何一個(gè)位置都可以用經(jīng)緯度表示,緯度的區(qū)間是 [-90, 90],經(jīng)度的區(qū)間 [-180, 180]。比如天安門的坐標(biāo)是 39.908,116.397,整體編碼過程如下:

一、對(duì)緯度 39.908 的編碼如下:

將緯度劃分2個(gè)區(qū)間,左區(qū)間 [-90, 0) 用 0 表示,右區(qū)間 [0, 90] 用 1 表示, 39.908 處在右區(qū)間,故第一位編碼是 1;在將 [0, 90] 劃分2個(gè)區(qū)間,左區(qū)間 [0, 45) 用 0 表示,右區(qū)間 [45, 90] 用 1 表示,39.908處在左區(qū)間, 故第二位編碼是 0;同1、2的計(jì)算步驟,39.908 的最后10位編碼是 “10111 00011”

二、對(duì)經(jīng)度 116.397 的編碼如下:

將經(jīng)度劃分2個(gè)區(qū)間,左區(qū)間 [-180, 0) 用 0 表示,右區(qū)間 [0, 180] 用 1 表示,116.397處在右區(qū)間, 故第一位編碼是 1;在將 [0, 180] 劃分2個(gè)區(qū)間,左區(qū)間 [0, 90) 用 0 表示,右區(qū)間 [90, 180] 用 1 表示,116.397處在右區(qū)間,故第二位編碼是 1;同1、2的計(jì)算步驟,116.397 的最后6位編碼是 “11010 01011”

三、合并組碼

將奇數(shù)位放經(jīng)度,偶數(shù)位放緯度,把2串編碼組合生成新串:“11100 11101 00100 01111”;通過 Base32 編碼,每5個(gè)二進(jìn)制編碼一個(gè)數(shù),“28 29 04 15”根據(jù) Base32 表,得到 Geo Hash 為:“WX4G”

即最后天安門的4位 Geo Hash 為 “WX4G”,如果需要經(jīng)度更準(zhǔn)確,在對(duì)應(yīng)的經(jīng)緯度編碼粒度再往下追溯即可。

附:Base32 編碼圖

Geo Hash 如何用于地理搜索?

舉個(gè)例子,搜索天安門附近 200 米的景點(diǎn),如下是天安門附近的Geo編碼

搜索過程如下:

首先確定天安門的Geo Hash為 WX4G0B,(6位區(qū)域碼約 0.34平分千米,約為長(zhǎng)寬600米區(qū)域)而6位編碼表示 600 米,半徑 300 米 > 要求的 200 米,搜索所有編碼為 WX4G0B 的景點(diǎn)即可但是由于天安門處于 WX4G0B 的邊緣位置,并不一定處在正中心。這就需要將 WX4G0B 附近的8個(gè)區(qū)域同時(shí)納入搜索,故搜索 WX4G0B、WX4G09、WX4G0C 一共9個(gè)編碼的景點(diǎn)第3步已經(jīng)將范圍縮小到很小的一個(gè)區(qū)間,但是得到的景點(diǎn)距離并不是準(zhǔn)確的,需要在通過距離計(jì)算過濾出小于 200 米的景點(diǎn),得到最終結(jié)果。

由上面步驟可以看出,Geo Hash 將原本大量的距離計(jì)算,變成一個(gè)字符串檢索縮小范圍后,再進(jìn)行小范圍的距離計(jì)算,及快速又準(zhǔn)確的進(jìn)行距離搜索。

Geo Hash 依據(jù)的數(shù)學(xué)原理

如圖所示,我們將二進(jìn)制編碼的結(jié)果填寫到空間中,當(dāng)將空間劃分為四塊時(shí)候,編碼的順序分別是左下角00,左上角01,右下腳10,右上角11,也就是類似于Z的曲線。當(dāng)我們遞歸的將各個(gè)塊分解成更小的子塊時(shí),編碼的順序是自相似的(分形),每一個(gè)子快也形成Z曲線,這種類型的曲線被稱為Peano空間填充曲線。

這種類型的空間填充曲線的優(yōu)點(diǎn)是將二維空間轉(zhuǎn)換成一維曲線(事實(shí)上是分形維),對(duì)大部分而言,編碼相似的距離也相近, 但Peano空間填充曲線最大的缺點(diǎn)就是突變性,有些編碼相鄰但距離卻相差很遠(yuǎn),比如0111與1000,編碼是相鄰的,但距離相差很大。

除Peano空間填充曲線外,還有很多空間填充曲線,如圖所示,其中效果公認(rèn)較好是Hilbert空間填充曲線,相較于Peano曲線而言,Hilbert曲線沒有較大的突變。為什么GeoHash不選擇Hilbert空間填充曲線呢?可能是Peano曲線思路以及計(jì)算上比較簡(jiǎn)單吧,事實(shí)上,Peano曲線就是一種四叉樹線性編碼方式。

Part 5、數(shù)值索引

Lucene的倒排索引決定,索引內(nèi)容是一個(gè)可排序的字符串,如果要查找一個(gè)數(shù)字,那么也需要將數(shù)字轉(zhuǎn)成字符串。這樣,檢索一個(gè)數(shù)字是沒問題的,如果需要搜索一個(gè)數(shù)值范圍,怎么做呢?

要做范圍查找,那么要求數(shù)字轉(zhuǎn)成的字符串也是有序并單調(diào)的,但數(shù)字本身的位數(shù)是不一樣的,最簡(jiǎn)單的版本就是前綴補(bǔ)0,比如 35, 234, 1 都補(bǔ)成 4 位,得到 0035, 0234, 0001,這樣能保證:

數(shù)字(a) > 數(shù)字(b) ===> 字符串(a) > 字符串(b)

這時(shí)候,查詢應(yīng)該用范圍內(nèi)的所有數(shù)值或查詢,比如查詢 [33, 36) 這個(gè)范圍,對(duì)應(yīng)的查詢語法是:

33 || 34 || 35

嗯看起來很好的解決了范圍查詢,但是,這樣存在3個(gè)問題:

補(bǔ)位多少合適呢?總有一個(gè)數(shù)字會(huì)超出你的補(bǔ)位范圍因?yàn)榇嬖谘a(bǔ)位,就會(huì)多出很多的空間,這在搜索引擎里寶貴的內(nèi)存是無法接受的如果是范圍查詢,需要用多次或查詢,性能并不高

故,涉及到范圍不能簡(jiǎn)單的做字符串補(bǔ)位轉(zhuǎn)換,是否存在及節(jié)省空間,又能更高效解決問題的方案呢?

就是:

數(shù)值Trie樹,下面詳細(xì)介紹

上面說了怎么索引,那么Query呢?比如我給你一個(gè)Range Query從423-642,怎么找到那6個(gè)term呢?

我們首先可以用shift==0找到范圍的起點(diǎn)后終點(diǎn)(有可能沒有相等的,比如搜索422,也會(huì)找到423)。然后一直往上找,直到找到一個(gè)共同的祖先(肯定能找到,因?yàn)闃涓撬腥~子節(jié)點(diǎn)的祖先),對(duì)應(yīng)起點(diǎn),每次往上走的時(shí)候, 左邊范圍節(jié)點(diǎn)都要把它右邊的兄弟節(jié)點(diǎn)都加進(jìn)去, 右邊范圍節(jié)點(diǎn)都要把它左邊的兄弟節(jié)點(diǎn)加進(jìn)去, 若已經(jīng)到達(dá)頂點(diǎn), 則是將左邊范圍節(jié)點(diǎn)和右邊范圍節(jié)點(diǎn)之間的節(jié)點(diǎn)加進(jìn)行去

查找423到642之間的具體的區(qū)間:

423-429,640-64243-49,60-635-5

另外還有一個(gè)問題,比如423會(huì)被分詞成423,42和4,那么4也會(huì)被分詞成4,那么4表示哪個(gè)呢?

所以intToPrefixCoded方法會(huì)額外用一個(gè)char來保存shift:buffer[0] = (char)(SHIFT_START_INT + shift);

比如423分詞的4的shift是2(這里是10進(jìn)制的例子,二進(jìn)制也是同樣的),423分成423的shift是0,4的shift是0,因此前綴肯定比后綴大。

最后,由于索引在判斷時(shí)無需感知是否是數(shù)字,可以把所有的數(shù)字當(dāng)成二進(jìn)制處理,這樣在存儲(chǔ)和效率上更高。

三、搜索引擎的極致優(yōu)化

LSM思想

LSM (Log Structured Merge Tree),最早是谷歌的 “BigTable” 提出來的,目標(biāo)是保證寫入性能,同時(shí)又能支持較高效率的檢索,在很多 NoSQL 中都有使用,Lucene 也是使用 LSM 思想來寫入。

普通的B+樹增加記錄可能需要執(zhí)行 seek+update 操作,這需要大量磁盤尋道移動(dòng)磁頭。而 LSM 采用記錄在文件末尾,順序?qū)懭霚p少移動(dòng)磁頭/尋道,執(zhí)行效率高于 B+樹。具體 LSM 的原理是什么呢?

為了保持磁盤的IO效率,lucene避免對(duì)索引文件的直接修改,所有的索引文件一旦生成,就是只讀,不能被改變的。其操作過程如下:

在內(nèi)存中保存新增的索引, 內(nèi)存緩存(也就是memtable);內(nèi)存中的索引數(shù)量達(dá)到一定閾值時(shí),觸發(fā)寫操作,將這部分?jǐn)?shù)據(jù)批量寫入新文件,我們稱為segment;也就是 sstable文件新增的segment生成后,不能被修改;update操作和delete操作不會(huì)立即導(dǎo)致原有的數(shù)據(jù)被修改或者刪除,會(huì)以append的方式存儲(chǔ)update和delete標(biāo)記;最終得到大量的 segment,為了減少資源占用,也提高檢索效率,會(huì)定期的將這些小的 segment 合并成大的 segment,由于map中的數(shù)據(jù)都是排好序的,所以合并也不會(huì)有隨機(jī)寫操作;通過merge,還可以把update和delete操作真正生效,刪除多余的數(shù)據(jù),節(jié)省空間。

合并的過程:

Basic Compaction

每個(gè)文件固定N個(gè)數(shù)量,超過N,則新建一個(gè)sstable;當(dāng)sstable數(shù)大于M,則合并一個(gè)大sstable;當(dāng)大sstable的數(shù)量大于M,則合并一個(gè)更大的sstable文件,依次類推。

但是,這會(huì)出現(xiàn)一個(gè)問題,就是大量的文件被創(chuàng)建,在最壞的情況下,所有的文件都要搜索。

Levelled Compaction

像 LevelDB 和 Cassandra解決這個(gè)問題的方法是:實(shí)現(xiàn)了一個(gè)分層的,而不是根據(jù)文件大小來執(zhí)行合并操作。

每層維護(hù)指定數(shù)量的文件,保證不讓 key 重疊,查找一個(gè) key 只會(huì)查找一個(gè) key;每次文件只會(huì)被合并到上一層的一個(gè)文件。當(dāng)一層的文件數(shù)滿足特定個(gè)數(shù)時(shí),合并到上一層。

所以, LSM 是日志和傳統(tǒng)的單文件索引(B+ tree,Hash Index)的中立,他提供一個(gè)機(jī)制來管理更小的獨(dú)立的索引文件(sstable)。

通過管理一組索引文件而不是單一的索引文件,LSM 將B+樹等結(jié)構(gòu)昂貴的隨機(jī)IO變的更快,而代價(jià)就是讀操作要處理大量的索引文件(sstable)而不是一個(gè),另外還是一些IO被合并操作消耗。

Lucene的Segment設(shè)計(jì)思想,與LSM類似但又有些不同,繼承了LSM中數(shù)據(jù)寫入的優(yōu)點(diǎn),但是在查詢上只能提供近實(shí)時(shí)而非實(shí)時(shí)查詢。

Segment在被flush或commit之前,數(shù)據(jù)保存在內(nèi)存中,是不可被搜索的,這也就是為什么Lucene被稱為提供近實(shí)時(shí)而非實(shí)時(shí)查詢的原因。讀了它的代碼后,發(fā)現(xiàn)它并不是不能實(shí)現(xiàn)數(shù)據(jù)寫入即可查,只是實(shí)現(xiàn)起來比較復(fù)雜。原因是Lucene中數(shù)據(jù)搜索依賴構(gòu)建的索引(例如倒排依賴Term Dictionary),Lucene中對(duì)數(shù)據(jù)索引的構(gòu)建會(huì)在Segment flush時(shí),而非實(shí)時(shí)構(gòu)建,目的是為了構(gòu)建最高效索引。當(dāng)然它可引入另外一套索引機(jī)制,在數(shù)據(jù)實(shí)時(shí)寫入時(shí)即構(gòu)建,但這套索引實(shí)現(xiàn)會(huì)與當(dāng)前Segment內(nèi)索引不同,需要引入額外的寫入時(shí)索引以及另外一套查詢機(jī)制,有一定復(fù)雜度。

FST

數(shù)據(jù)字典 Term Dictionary,通常要從數(shù)據(jù)字典找到指定的詞的方法是,將所有詞排序,用二分查找即可。這種方式的時(shí)間復(fù)雜度是 Log(N),占用空間大小是 O(N*len(term))。缺點(diǎn)是消耗內(nèi)存,存在完整的term,當(dāng) term 數(shù)達(dá)到上千萬時(shí),占用內(nèi)存非常大。

lucene從4開始大量使用的數(shù)據(jù)結(jié)構(gòu)是FST(Finite State Transducer)。FST有兩個(gè)優(yōu)點(diǎn):

空間占用小,通過讀 term 拆分復(fù)用及前綴和后綴的重用,壓縮了存儲(chǔ)空間;查詢速度快,查詢僅有 O(len(term)) 時(shí)間復(fù)雜度

那么 FST 數(shù)據(jù)結(jié)構(gòu)是什么原理呢? 先來看看什么是 FSM (Finite State Machine), 有限狀態(tài)機(jī),從“起始狀態(tài)”到“終止?fàn)顟B(tài)”,可接受一個(gè)字符后,自循環(huán)或轉(zhuǎn)移到下一個(gè)狀態(tài)。

而FST呢,就是一種特殊的 FSM,在 Lucene 中用來實(shí)現(xiàn)字典查找功能(NLP中還可以做轉(zhuǎn)換功能),F(xiàn)ST 可以表示成FST的形式

舉例:對(duì)“cat”、 “deep”、 “do”、 “dog” 、“dogs” 這5個(gè)單詞構(gòu)建FST(注:必須已排序),結(jié)構(gòu)如下:

當(dāng)存在 value 為對(duì)應(yīng)的 docId 時(shí),如 cat/0 deep/1 do/2 dog/3 dogs/4, FST 結(jié)構(gòu)圖如下:

FST 還有一個(gè)特點(diǎn),就是在前綴公用的基礎(chǔ)上,還會(huì)做一個(gè)后綴公用,目標(biāo)同樣是為了壓縮存儲(chǔ)空間。

其中紅色的弧線表 NEXT-optimized,可以通過 畫圖工具 來測(cè)試。

SkipList

為了能夠快速查找docid,lucene采用了SkipList這一數(shù)據(jù)結(jié)構(gòu)。SkipList有以下幾個(gè)特征:

元素排序的,對(duì)應(yīng)到我們的倒排鏈,lucene是按照docid進(jìn)行排序,從小到大;跳躍有一個(gè)固定的間隔,這個(gè)是需要建立SkipList的時(shí)候指定好,例如下圖以間隔是;SkipList的層次,這個(gè)是指整個(gè)SkipList有幾層

在什么位置設(shè)置跳表指針?

? 設(shè)置較多的指針,較短的步長(zhǎng), 更多的跳躍機(jī)會(huì)

? 更多的指針比較次數(shù)和更多的存儲(chǔ)空間

? 設(shè)置較少的指針,較少的指針比較次數(shù),但是需要設(shè)置較長(zhǎng)的步長(zhǎng)\uf0de較少的連續(xù)跳躍

如果倒排表的長(zhǎng)度是L,那么在每隔一個(gè)步長(zhǎng)S處均勻放置跳表指針。

BKD Tree

也叫 Block KD-tree,根據(jù)FST思路,如果查詢條件非常多,需要對(duì)每個(gè)條件根據(jù) FST 查出結(jié)果,進(jìn)行求并集操作。如果是數(shù)值類型,那么潛在的 Term 可能非常多,查詢銷量也會(huì)很低,為了支持高效的數(shù)值類或者多維度查詢,引入 BKD Tree。在一維下就是一棵二叉搜索樹,在二維下是如果要查詢一個(gè)區(qū)間,logN的復(fù)雜度就可以訪問到葉子節(jié)點(diǎn)對(duì)應(yīng)的倒排鏈。

確定切分維度,這里維度的選取順序是數(shù)據(jù)在這個(gè)維度方法最大的維度優(yōu)先。一個(gè)直接的理解就是,數(shù)據(jù)分散越開的維度,我們優(yōu)先切分。切分點(diǎn)的選這個(gè)維度最中間的點(diǎn)。遞歸進(jìn)行步驟1,2,我們可以設(shè)置一個(gè)閾值,點(diǎn)的數(shù)目少于多少后就不再切分,直到所有的點(diǎn)都切分好停止。BitSet 過濾

二進(jìn)制處理,通過BKD-Tree查找到的docID是無序的,所以要么先轉(zhuǎn)成有序的docID數(shù)組,或者構(gòu)造BitSet,然后再與其他結(jié)果合并。

IndexSorting

IndexSorting是一種預(yù)排序,在ES6.0之后才有,與查詢時(shí)的Sort不同,IndexSorting是一種預(yù)排序,即數(shù)據(jù)預(yù)先按照某種方式進(jìn)行排序,它是Index的一個(gè)設(shè)置,不可更改。

一個(gè)Segment中的每個(gè)文檔,都會(huì)被分配一個(gè)docID,docID從0開始,順序分配。在沒有IndexSorting時(shí),docID是按照文檔寫入的順序進(jìn)行分配的,在設(shè)置了IndexSorting之后,docID的順序就與IndexSorting的順序一致。

舉個(gè)例子來說,假如文檔中有一列為Timestamp,我們?cè)贗ndexSorting中設(shè)置按照Timestamp逆序排序,那么在一個(gè)Segment內(nèi),docID越小,對(duì)應(yīng)的文檔的Timestamp越大,即按照Timestamp從大到小的順序分配docID。

IndexSorting 之所以可以優(yōu)化性能,是因?yàn)榭梢蕴崆爸袛嘁约疤岣邤?shù)據(jù)壓縮率,但是他并不能滿足所有的場(chǎng)景,比如使用非預(yù)排序字段排序,還會(huì)損耗寫入時(shí)的性能。

搜索引擎正是靠?jī)?yōu)秀的理論加極致的優(yōu)化,做到查詢性能上的極致,后續(xù)會(huì)再結(jié)合源碼分析壓縮算法如何做到極致的性能優(yōu)化的。

未完待續(xù)~

附:進(jìn)一步閱讀

http://lucene.apache.org/

https://wiki.apache.org/lucene-java/FrontPage

https://zhuanlan.zhihu.com/p/35814539

http://www.runoob.com/java/java-bitset-class.html

https://www.cnblogs.com/skycore/p/5093257.html

https://www.cnblogs.com/LBSer/p/4119841.html

https://blog.csdn.net/zhufenglonglove/article/details/51700898

https://www.jianshu.com/p/1e498888f505

http://www.nosqlnotes.com/technotes/searchengine/lucene-invertedindex/

https://www.jianshu.com/p/69d56f9c0576

作者:yhzhtk

以上就是關(guān)于刷卡機(jī)磁頭的原理的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于刷卡機(jī)磁頭的原理的知識(shí),希望能夠幫助到大家!

轉(zhuǎn)載請(qǐng)帶上網(wǎng)址:http://www.yadikedp.com/shuaka/163751.html

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 [email protected] 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。
聯(lián)系我們
訂購(gòu)聯(lián)系:小莉
微信聯(lián)系方式
地址:深圳市寶安區(qū)固戍聯(lián)誠(chéng)發(fā)產(chǎn)業(yè)園木星大廈

公司地址:深圳市寶安區(qū)固戍聯(lián)誠(chéng)發(fā)產(chǎn)業(yè)園木星大廈

舉報(bào)投訴 免責(zé)申明 版權(quán)申明 廣告服務(wù) 投稿須知 技術(shù)支持:第一POS網(wǎng) Copyright@2008-2030 深圳市慧聯(lián)實(shí)業(yè)有限公司 備案號(hào):粵ICP備18141915號(hào)

  • <bdo id="ogrsz"></bdo>
      1. <pre id="ogrsz"><abbr id="ogrsz"></abbr></pre>
        <p id="ogrsz"></p>
        <bdo id="ogrsz"></bdo>
        主站蜘蛛池模板: 汝城县| 柳江县| 泗阳县| 驻马店市| 吉林省| 鸡泽县| 美姑县| 嘉祥县| 梅州市| 彰武县| 会泽县| 武强县| 荔波县| 固安县| 神农架林区| 龙川县| 清水县| 平乡县| 太仓市| 盘山县| 双鸭山市| 安福县| 赣榆县| 桐乡市| 肃宁县| 大化| 奉节县| 乐平市| 公主岭市| 永安市| 伊通| 凤山县| 九龙城区| 邵东县| 肃北| 灵山县| 西安市| 洛川县| 麻栗坡县| 八宿县| 城口县|