sonic——可替代Elasticsearch的簡單搜索引擎

簡介

近期,筆者在github上發(fā)現(xiàn)了一個十分好玩的開源項目——sonic。sonic項目的介紹十分簡單媳危。

?? Fast, lightweight & schema-less search backend. An alternative to Elasticsearch that runs on a few MBs of RAM.

在這段話中,我們可以很迅速的了解sonic的特性。

首先既荚,它很快,比Elasticsearch還要快很多栋艳,在官方給出的benchmark中恰聘,它的搜索都在毫秒級別的。

第二吸占,它輕量晴叨,Elasticsearch在漫長的發(fā)展過程中,已經(jīng)變得越來越沉了矾屯,不僅支持搜索兼蕊,存儲,分析件蚕,可視化孙技,Elasticsearch還擁抱上了大數(shù)據(jù),使Elasticsearch的學習曲線很高排作,而且使用成本也很高牵啦,普通的機器已經(jīng)完全不夠用了,而sonic十分的輕妄痪,上手快哈雏,API少,專注于搜索這一塊衫生。

第三裳瘪,無范式(schema-less)。請原諒我這樣翻譯罪针,Elasticsearch在使用中你需要先定義mappings來讓數(shù)據(jù)格式化彭羹。很多時候,定義固定結(jié)構(gòu)去存儲數(shù)據(jù)本應該是數(shù)據(jù)庫該干的事站故,但是Elasticsearch支持了數(shù)據(jù)存儲皆怕,因此你必須先完成這一步才能使用Elasticsearch毅舆。而sonic是無范式的,sonic不做數(shù)據(jù)的存儲愈腾,它只做搜索憋活,因此你不需要做mappings。

第四虱黄,省錢悦即。在任何實際項目的開發(fā)和運維中,成本大多時候被放在了第一位橱乱,sonic對于運行機的要求很低辜梳,且內(nèi)存占用少,可以為你省下一大筆的開支泳叠。

說了這么多作瞄,你是否也想嘗試一下sonic?接下來我們一起來實操一下危纫,看看能否窺一斑而知全豹宗挥。

使用

安裝

首先一點,sonic不支持windows种蝶,因此最好的使用方式便是docker契耿,所以請先確保你會簡單的使用docker,僅僅需要知道一些概念即可螃征。

請在終端鍵入如下命令:

docker pull valeriansaliou/sonic:v1.2.0

等待一會兒搪桂,docker會幫我們搞定一切,拉取完成之后盯滚,我們需要一份簡單的sonic配置文件——config.cfg踢械。配置文件內(nèi)容如下:

# Sonic
# Fast, lightweight and schema-less search backend
# Configuration file
# Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg


[server]

log_level = "debug"


[channel]

inet = "0.0.0.0:1491"
tcp_timeout = 300

auth_password = "SecretPassword"

[channel.search]

query_limit_default = 10
query_limit_maximum = 100
query_alternates_try = 4

suggest_limit_default = 5
suggest_limit_maximum = 20


[store]

[store.kv]

path = "/var/lib/sonic/store/kv/"

retain_word_objects = 1000

[store.kv.pool]

inactive_after = 1800

[store.kv.database]

flush_after = 900

compress = true
parallelism = 2
max_files = 100
max_compactions = 1
max_flushes = 1
write_buffer = 16384
write_ahead_log = true

[store.fst]

path = "/var/lib/sonic/store/fst/"

[store.fst.pool]

inactive_after = 300

[store.fst.graph]

consolidate_after = 180

在這份配置文件中,你可能只需要注意兩個點:

  • inet魄藕,sonic的監(jiān)聽端口裸燎,這里默認為"0.0.0.0:1491"
  • auth_password泼疑,sonic的密碼,這里默認為"SecretPassword"荷荤。

sonic在通信協(xié)議上選擇了更加高效的tcp協(xié)議退渗,并且衍生了自己的一套腳本語言,放心僅僅只是幾句簡單的查詢操作語句蕴纳。

請將配置文件存放在一個合適的位置存儲会油,如筆者的存儲位置在/Users/pedro/Desktop/sonic-test/config.cfg

在終端輸入如下命令古毛,我們開啟一個sonic服務:

docker run -p 1491:1491 -v ~/Desktop/sonic-test/config.cfg:/etc/sonic.cfg  valeriansaliou/sonic:v1.2.0

等待一會兒翻翩,如果終端出現(xiàn)如下信息都许,則代表運行成功:

(INFO) - starting up
(INFO) - started
(DEBUG) - spawn managed thread: tasker
(DEBUG) - spawn managed thread: channel
(INFO) - tasker is now active
(INFO) - listening on tcp://0.0.0.0:1491

概念

在具體的數(shù)據(jù)操作之前,我們十分有必要的去了解一下sonic的工作機制嫂冻。請記住胶征,這很重要,了解它你才會有足夠清晰的大局觀桨仿,才有可能做到窺一斑而知全豹睛低。

sonic的操作可分為三個模式:

  • Search mode(搜索模式),sonic的模式區(qū)分很是硬核服傍,在搜索模式下钱雷,你只能進行搜索相關的操作,不能進行數(shù)據(jù)插入和備份的相關操作吹零。核心的有QUERYSUGGEST兩個操作罩抗,分別用來對進行搜索和對進行補全。
  • Ingest mode(插入模式)灿椅,請記住sonic只有在插入模式下才能進行數(shù)據(jù)的插入套蒂。sonic的數(shù)據(jù)插入核心的有三個操作,分別是PUSH阱扬、POPFLUSH泣懊。push會向存儲區(qū)中添加一個元素,pop則是從存儲區(qū)中彈出這個元素麻惶,flush則會將存儲區(qū)中的元素全部清除馍刮。
  • Control mode(控制模式),sonic可以在控制模式下窃蹋,對數(shù)據(jù)進行鞏固卡啰,備份和恢復等一系列的操作。核心的操作有TRIGGERINFO警没,trigger主要對數(shù)據(jù)進行鞏固匈辱,備份和恢復,而info用于查看sonic的運行狀態(tài)杀迹。

在剛才我們談到過了sonic的協(xié)議亡脸,我們把它稱作Sonic Channel protocol。這份協(xié)議構(gòu)建在tcp的協(xié)議之上树酪,如果你熟悉redis的話浅碾,你可能會發(fā)現(xiàn),二者很是相似续语。

sonic在此協(xié)議上衍生了這三大模式以及相關的操作垂谢,不難發(fā)現(xiàn),sonic的核心概念和使用真的十分簡單疮茄,當然了筆者不可能在此處全盤拖出滥朱,在sonic的文檔中詳細的給出了Sonic Channel protocol的具體細節(jié)和實用方法根暑,如果感興趣,請務必了解一下徙邻。

操作

sonic的服務運行起來以后排嫌,我們通過telnet這個實用的工具來操作一下它。

在終端輸入:

telnet localhost 1491

出現(xiàn)如下信息表示你連接成功鹃栽。

Trying ::1...
Connected to localhost.
Escape character is '^]'.
CONNECTED <sonic-server v1.2.0>

在真正的插入之前躏率,我們還需要對sonic的存儲做一下簡單的概述。在文章的開頭民鼓,筆者說到sonic只關注于搜索薇芝,而將數(shù)據(jù)的存儲交給了其它的數(shù)據(jù)庫去實現(xiàn)。那么sonic真的不需要存儲嗎丰嘉?

答案顯而易見夯到,需要!難道這是欺騙嗎饮亏?當然不是耍贾,sonic不做數(shù)據(jù)的存儲,但它需要對搜索的部分數(shù)據(jù)做索引和存儲路幸。你可能會覺得有些繞荐开,沒關系,我們舉個例子简肴。

一篇文章晃听,可能有標題,綜述砰识,正文能扒,作者...等一系列的數(shù)據(jù)。那么在搜索這篇文章的時候辫狼,我們不可能搜索這所有的字段數(shù)據(jù)初斑,我們往往會采取一種折中的方式,搜索某幾個字段的數(shù)據(jù)膨处。例如:我們搜索綜述和標題见秤,而放棄搜索龐大的正文數(shù)據(jù),這既提高了搜索效率真椿,也降低了搜索成本秦叛。

這個時候,你再來理解瀑粥,sonic它確實不做存儲,它不會存儲這篇文章的所有字段三圆,即不會存儲標題狞换,綜述避咆,正文,作者等等修噪,但是它需要存儲它用來做搜索的部分數(shù)據(jù)查库,即綜述和標題。相比存儲所有字段的龐大數(shù)據(jù)黄琼,綜述和標題僅僅占了很小的一部分樊销。

好,重點來了脏款!sonic如何存儲這些有效的搜索數(shù)據(jù)的呢围苫?sonic有兩個存儲點,一個是kv存儲撤师,一個是fst存儲剂府。kv存儲很好理解,即key-value存儲剃盾,我們需要把綜述和標題合并成一個value腺占,并為它取上唯一的key,這個key一般對應數(shù)據(jù)庫的主鍵痒谴,sonic會把這兩個值存儲到kv區(qū)衰伯。

對于把綜述和標題合并成一個value,我想很多人會有些許不理解积蔚,把它們合并了還怎么搜索了意鲸?不用怕,sonic會自動幫我們做分詞库倘,并將其通過倒排索引的方式存儲起來临扮,當你在通過詞搜索的時候,一般情況下只會取幾個詞做搜索教翩,而不會取全部杆勇,所以即使合并起來,影響也不大饱亿,當然你也可以僅選擇一個字段做value蚜退,這樣就不會有合并的問題。

好彪笼,上段之中钻注,我們拋出了倒排索引這個概念,在此處筆者對其不做詳細解釋配猫,如果你想了解幅恋,查詢一些資料即可。你可以簡單理解為倒排就是通過來找句子泵肄,索引會存儲句子之間的關聯(lián)捆交,然后通過搜索傳來的詞來反向?qū)ふ揖渥邮缫怼4颂幠憧赡芤呀?jīng)意識到了,這些索引是不是要存儲到fst區(qū)啊品追。是的玄括,這些倒排索引會存儲到fst區(qū),與kv區(qū)良好的分開肉瓦。

插入數(shù)據(jù)

好了遭京,談了這么多,我們終于可以進入到實操環(huán)節(jié)了泞莉。通過telnet連接sonic之后哪雕,我們嘗試插入一條數(shù)據(jù)。

telnet localhost 1491
Trying ::1...
Connected to localhost.
Escape character is '^]'.
CONNECTED <sonic-server v1.2.0>

# 此處以 START 開始 ingest模式 SecretPassword 是密碼戒财,務必輸入密碼
START ingest SecretPassword
# sonic的返回信息
STARTED ingest protocol(1) buffer(20000)
# 通過PUSH 插入數(shù)據(jù)
# movie 為 collection名
# douban 為 bucket 名
# 1 為 object 名 即 key 值
# "the knight" 為 value 值
PUSH movie douban 1 "the knight"
# 插入成功后的返回值 ok
OK
# 退出
QUIT
ENDED quit

筆者已經(jīng)在注釋中热监,詳細的解釋了每一行命令的作用,但這可能還是不夠友好饮寞。sonic每次連接都可以被理解成一次會話(session)孝扛,這個會話從START命令開始,當然如果通過telnet連接后一段時間未執(zhí)行start幽崩,sonic會自動關閉掉這個連接苦始。

START命令后,會開始一個會話慌申。具體的命令格式為START <mode> <password>陌选,如START ingest SecretPassword會開啟插入模式(ingest model),密碼為SecretPassword蹄溉。sonic鑒權(quán)成功后咨油,返回會話建立成功的信息STARTED ingest protocol(1) buffer(20000)

隨后柒爵,再通過PUSH命令插入一條數(shù)據(jù)役电,命令格式為PUSH <collection> <bucket> <object> "<text>"。這里注意:sonic與大多數(shù)數(shù)據(jù)庫一樣都有層級的概念棉胀,如在mongodb中有 數(shù)據(jù)庫 -> 集合 -> 項 -> 字段的層級概念法瑟,sonic也有 collection -> bucket -> [object:text]的層次。

當然有人會問唁奢,這有啥用蚌?就但這條語句PUSH movie douban 1 "the knight"而言麻掸,它就可以看到層級的作用酥夭,它可以將搜索數(shù)據(jù)分類,更為重要的是,the knight歸到了movie集合下的douban桶采郎,而當有其它的集合時千所,如song,我們可以有效的在某個集合的某個桶下進行有效的搜索蒜埋。

插入成功后该贾,返回一個OK别凤。

搜索數(shù)據(jù)

插入數(shù)據(jù)后杏节,我們嘗試再次連接须鼎,并用搜索模式進入一個會話低剔。

# 開始一個搜索會話
START search SecretPassword
STARTED search protocol(1) buffer(20000)
# 搜索 movie -> douban 下的數(shù)據(jù)亲善,搜索關鍵字為 the
QUERY movie douban "the"
PENDING Q5Z3lY25
# 得到搜索結(jié)果向臀,返回object工三,即key值 1
EVENT QUERY Q5Z3lY25 1

搜索作為sonic的最最最重要的部分犯建,使用起來極其簡單讲冠,但卻十分強大。其命令格式為QUERY <collection> <bucket> "<terms>" [LIMIT(<count>)]? [OFFSET(<count>)]?适瓦,熟悉sql的立馬就能理解如何使用了竿开,collection和bucket表示詳細的層級關系,terms表示搜索的關鍵詞玻熙,limit 限制返回結(jié)果的數(shù)量否彩,offset表示結(jié)果的偏移量。

PENDING Q5Z3lY25
EVENT QUERY Q5Z3lY25 1

這兩行均是搜索之后嗦随,sonic的返回信息列荔,表示發(fā)生了一個事件,事件id為Q5Z3lY25枚尼,得到的結(jié)果是1贴浙。

sonic還支持單詞的自動補全,如輸入th署恍,它會返回the這個單詞崎溃,幫助你的搜索進行自動補全,提高用戶體驗锭汛。具體的格式是:SUGGEST <collection> <bucket> "<word>" [LIMIT(<count>)]?笨奠。

START search SecretPassword
STARTED search protocol(1) buffer(20000)
# 輸入 th 這兩次字母
SUGGEST movie douban "th"
PENDING SukqsbYk
# 返回 the 這個已經(jīng)補全的單詞
EVENT SUGGEST SukqsbYk the

這里要注意一下,SUGGEST僅僅支持limit這一個項唤殴,在書寫命令的時候請一定保持大寫即LIMIT般婆。

其它

sonic在控制模式下,可以對數(shù)據(jù)進行consolidate加固朵逝,backup備份蔚袍,restore恢復,以及INFO查看sonic服務的數(shù)據(jù)等操作。

這些操作對于數(shù)據(jù)維護以及服務運維來說很重要啤咽,但顯然不是這篇文章的重點晋辆。以上的全部操作,均可以在sonic的文檔中找到宇整,如果你感興趣瓶佳,請務必閱讀一下,它真的很少鳞青,很方便上手霸饲。

結(jié)語

在文章開頭到結(jié)尾,筆者介紹了sonic的特性和它的一些概念臂拓,以及部分的工作原理厚脉。如果你單純的想要去使用sonic,那么請記住胶惰,熟悉本文提到的概念傻工,保證對sonic的大局觀的理解,詳細閱讀一下它的文檔孵滞,那么你就可以去嘗試使用sonic中捆。

到此,我們幾乎介紹到了sonic的全部剃斧,相較于Elasticsearch轨香,它真的足夠小巧,足夠簡單幼东,將搜索做到了精細極致臂容。

在下篇文章中,筆者會使用python根蟹,mongodb做一個簡單的搜索應用脓杉,盡情期待吧,諸君简逮。

過度封裝帶來的簡單性球散,并不會帶來真正的簡單,只會帶來更加的復雜散庶〗堆撸——來自sonic和Elasticsearch的對比思考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市悲龟,隨后出現(xiàn)的幾起案子屋讶,更是在濱河造成了極大的恐慌,老刑警劉巖须教,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皿渗,死亡現(xiàn)場離奇詭異斩芭,居然都是意外死亡,警方通過查閱死者的電腦和手機乐疆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門划乖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挤土,你說我怎么就攤上這事琴庵。” “怎么了仰美?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵细卧,是天一觀的道長。 經(jīng)常有香客問我筒占,道長,這世上最難降的妖魔是什么蜘犁? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任翰苫,我火速辦了婚禮,結(jié)果婚禮上这橙,老公的妹妹穿的比我還像新娘奏窑。我一直安慰自己,他們只是感情好屈扎,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布埃唯。 她就那樣靜靜地躺著,像睡著了一般鹰晨。 火紅的嫁衣襯著肌膚如雪墨叛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天模蜡,我揣著相機與錄音漠趁,去河邊找鬼。 笑死忍疾,一個胖子當著我的面吹牛闯传,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卤妒,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼甥绿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了则披?” 一聲冷哼從身側(cè)響起共缕,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎收叶,沒想到半個月后骄呼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年蜓萄,在試婚紗的時候發(fā)現(xiàn)自己被綠了隅茎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫉沽,死狀恐怖辟犀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绸硕,我是刑警寧澤堂竟,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站玻佩,受9級特大地震影響出嘹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咬崔,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一税稼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垮斯,春花似錦郎仆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熊杨,卻和暖如春曙旭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猴凹。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工夷狰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郊霎。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓沼头,卻偏偏與公主長得像,于是被迫代替她去往敵國和親书劝。 傳聞我的和親對象是個殘疾皇子进倍,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容