内容简介:近期,笔者在github上发现了一个十分好玩的开源项目——在这段话中,我们可以很迅速的了解首先,它很快,比Elasticsearch还要快很多,在官方给出的benchmark中,它的搜索都在毫秒级别的。
近期,笔者在github上发现了一个十分好玩的开源项目—— sonic
。sonic项目的介绍十分简单。
? Fast, lightweight & schema-less search backend. An alternative to Elasticsearch that runs on a few MBs of RAM.
在这段话中,我们可以很迅速的了解 sonic 的特性。
首先,它很快,比Elasticsearch还要快很多,在官方给出的benchmark中,它的搜索都在毫秒级别的。
第二,它轻量,Elasticsearch在漫长的发展过程中,已经变得越来越沉了,不仅支持搜索,存储,分析,可视化,Elasticsearch还拥抱上了大数据,使Elasticsearch的学习曲线很高,而且使用成本也很高,普通的机器已经完全不够用了,而sonic十分的轻,上手快,API少,专注于搜索这一块。
第三,无范式(schema-less)。请原谅我这样翻译,Elasticsearch在使用中你需要先定义mappings来让数据格式化。很多时候,定义固定结构去存储数据本应该是数据库该干的事,但是Elasticsearch支持了数据存储,因此你必须先完成这一步才能使用Elasticsearch。而sonic是无范式的,sonic不做数据的存储,它只做搜索,因此你不需要做mappings。
第四,省钱。在任何实际项目的开发和运维中,成本大多时候被放在了第一位,sonic对于运行机的要求很低,且内存占用少,可以为你省下一大笔的开支。
说了这么多,你是否也想尝试一下 sonic
?接下来我们一起来实操一下,看看能否 窥一斑而知全豹
。
使用
安装
首先一点,sonic不支持windows,因此最好的使用方式便是 docker
,所以请先确保你会简单的使用docker,仅仅需要知道一些概念即可。
请在终端键入如下命令:
docker pull valeriansaliou/sonic:v1.2.0 复制代码
等待一会儿,docker会帮我们搞定一切,拉取完成之后,我们需要一份简单的sonic配置文件—— config.cfg
。配置文件内容如下:
# 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 复制代码
在这份配置文件中,你可能只需要注意两个点:
"0.0.0.0:1491" "SecretPassword"
sonic在通信协议上选择了更加高效的tcp协议,并且衍生了自己的一套脚本语言,放心仅仅只是几句简单的查询操作语句。
请将配置文件存放在一个合适的位置存储,如笔者的存储位置在 /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 复制代码
等待一会儿,如果终端出现如下信息,则代表运行成功:
(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 复制代码
概念
在具体的数据操作之前,我们十分有必要的去了解一下sonic的工作机制。请记住,这很重要,了解它你才会有足够清晰的大局观,才有可能做到 窥一斑而知全豹
。
sonic的操作可分为三个模式:
-
Search mode(搜索模式),sonic的模式区分很是硬核,在搜索模式下,你只能进行搜索相关的操作,不能进行数据插入和备份的相关操作。核心的有
QUERY
和SUGGEST
两个操作,分别用来对词
进行搜索和对字
进行补全。 -
Ingest mode(插入模式),请记住
sonic只有在插入模式下才能进行数据的插入
。sonic的数据插入核心的有三个操作,分别是PUSH
、POP
和FLUSH
。push会向存储区中添加一个元素,pop则是从存储区中弹出这个元素,flush则会将存储区中的元素全部清除。 -
Control mode(控制模式),sonic可以在控制模式下,对数据进行巩固,备份和恢复等一系列的操作。核心的操作有
TRIGGER
和INFO
,trigger主要对数据进行巩固,备份和恢,而info用于查看sonic的运行状态。
在刚才我们谈到过了sonic的协议,我们把它称作 Sonic Channel protocol
。这份协议构建在tcp的协议之上,如果你熟悉 redis 的话,你可能会发现,二者很是相似。
sonic在此协议上衍生了这三大模式以及相关的操作,不难发现,sonic的核心概念和使用真的十分简单,当然了笔者不可能在此处全盘拖出,在sonic的 文档
中详细的给出了 Sonic Channel protocol
的具体细节和实用方法,如果感兴趣,请务必了解一下。
操作
sonic的服务运行起来以后,我们通过 telnet
这个实用的 工具 来操作一下它。
在终端输入:
telnet localhost 1491 复制代码
出现如下信息表示你连接成功。
Trying ::1... Connected to localhost. Escape character is '^]'. CONNECTED <sonic-server v1.2.0> 复制代码
在真正的插入之前,我们还需要对sonic的 存储
做一下简单的概述。在文章的开头,笔者说到sonic只关注于搜索,而将数据的存储交给了其它的数据库去实现。那么sonic真的不需要存储吗?
答案显而易见,需要!难道这是欺骗吗?当然不是,sonic不做数据的存储,但它需要对搜索的部分数据做索引和存储。你可能会觉得有些绕,没关系,我们举个例子。
一篇文章,可能有标题,综述,正文,作者...等一系列的数据。那么在搜索这篇文章的时候,我们不可能搜索这所有的字段数据,我们往往会采取一种折中的方式,搜索某几个字段的数据。例如:我们搜索综述和标题,而放弃搜索庞大的正文数据,这既提高了搜索效率,也降低了搜索成本。
这个时候,你再来理解,sonic它确实不做存储,它不会存储这篇文章的所有字段,即不会存储标题,综述,正文,作者等等,但是它需要存储它用来做搜索的部分数据,即综述和标题。相比存储所有字段的庞大数据,综述和标题仅仅占了很小的一部分。
好,重点来了!sonic如何存储这些有效的搜索数据的呢?sonic有两个存储点,一个是 kv
存储,一个是 fst
存储。 kv
存储很好理解,即 key-value
存储,我们需要把综述和标题合并成一个 value
,并为它取上唯一的 key
,这个 key
一般对应数据库的主键,sonic会把这两个值存储到 kv
区。
对于把综述和标题合并成一个 value
,我想很多人会有些许不理解,把它们合并了还怎么搜索了?不用怕,sonic会自动帮我们做分词,并将其通过 倒排索引
的方式存储起来,当你在通过词搜索的时候,一般情况下只会取几个词做搜索,而不会取全部,所以即使合并起来,影响也不大,当然你也可以仅选择一个字段做 value
,这样就不会有合并的问题。
好,上段之中,我们抛出了 倒排索引
这个概念,在此处笔者对其不做详细解释,如果你想了解,查询一些资料即可。你可以简单理解为 倒排
就是通过 词
来找 句子
,索引会存储 词
和 句子
之间的关联,然后通过搜索传来的词来反向寻找句子。此处你可能已经意识到了,这些索引是不是要存储到 fst
区啊。是的,这些倒排索引会存储到 fst
区,与 kv
区良好的分开。
插入数据
好了,谈了这么多,我们终于可以进入到实操环节了。通过 telnet
连接sonic之后,我们尝试插入一条数据。
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 插入数据 # movie 为 collection名 # douban 为 bucket 名 # 1 为 object 名 即 key 值 # "the knight" 为 value 值 PUSH movie douban 1 "the knight" # 插入成功后的返回值 ok OK # 退出 QUIT ENDED quit 复制代码
笔者已经在注释中,详细的解释了每一行命令的作用,但这可能还是不够友好。sonic每次连接都可以被理解成一次会话(session),这个会话从 START
命令开始,当然如果通过telnet连接后一段时间未执行start,sonic会自动关闭掉这个连接。
START
命令后,会开始一个会话。具体的命令格式为 START <mode> <password>
,如 START ingest SecretPassword
会开启插入模式(ingest model),密码为 SecretPassword
。sonic鉴权成功后,返回会话建立成功的信息 STARTED ingest protocol(1) buffer(20000)
。
随后,再通过 PUSH
命令插入一条数据,命令格式为 PUSH <collection> <bucket> <object> "<text>"
。这里注意:sonic与大多数数据库一样都有 层级
的概念,如在 mongodb
中有 数据库 -> 集合 -> 项 -> 字段的层级概念,sonic也有 collection -> bucket -> [object:text]的层次。
当然有人会问,这有啥用啊?就但这条语句 PUSH movie douban 1 "the knight"
而言,它就可以看到层级的作用,它可以将搜索数据分类,更为重要的是,the knight归到了 movie
集合下的 douban
桶,而当有其它的集合时,如 song
,我们可以有效的在某个集合的某个桶下进行有效的搜索。
插入成功后,返回一个 OK
。
搜索数据
插入数据后,我们尝试再次连接,并用搜索模式进入一个会话。
# 开始一个搜索会话 START search SecretPassword STARTED search protocol(1) buffer(20000) # 搜索 movie -> douban 下的数据,搜索关键字为 the QUERY movie douban "the" PENDING Q5Z3lY25 # 得到搜索结果,返回object,即key值 1 EVENT QUERY Q5Z3lY25 1 复制代码
搜索作为sonic的最最最重要的部分,使用起来极其简单,但却十分强大。其命令格式为 QUERY <collection> <bucket> "<terms>" [LIMIT(<count>)]? [OFFSET(<count>)]?
,熟悉 sql
的立马就能理解如何使用了,collection和bucket表示详细的层级关系,terms表示搜索的关键词,limit 限制返回结果的数量,offset表示结果的偏移量。
PENDING Q5Z3lY25 EVENT QUERY Q5Z3lY25 1 复制代码
这两行均是搜索之后,sonic的返回信息,表示发生了一个事件,事件id为Q5Z3lY25,得到的结果是 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 这个已经补全的单词 EVENT SUGGEST SukqsbYk the 复制代码
这里要注意一下, SUGGEST
仅仅支持limit这一个项,在书写命令的时候请一定保持大写即 LIMIT
。
其它
sonic在控制模式下,可以对数据进行 consolidate
加固, backup
备份, restore
恢复,以及 INFO
查看sonic服务的数据等操作。
这些操作对于数据维护以及服务运维来说很重要,但显然不是这篇文章的重点。以上的全部操作,均可以在sonic的 文档 中找到,如果你感兴趣,请务必阅读一下,它真的很少,很方便上手。
结语
在文章开头到结尾,笔者介绍了sonic的特性和它的一些概念,以及部分的工作原理。如果你单纯的想要去使用sonic,那么请记住,熟悉本文提到的概念,保证对sonic的大局观的理解,详细阅读一下它的文档,那么你就可以去尝试使用sonic。
到此,我们几乎介绍到了sonic的全部,相较于Elasticsearch,它真的足够小巧,足够简单,将搜索做到了精细极致。
在下篇文章中,笔者会使用 python
, mongodb
做一个简单的搜索应用,尽情期待吧,诸君。
过度封装带来的简单性,并不会带来真正的简单,只会带来更加的复杂。——来自sonic和Elasticsearch的对比思考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Rails
David Griffiths / O'Reilly Media / 2008-12-30 / USD 49.99
Figure its about time that you hop on the Ruby on Rails bandwagon? You've heard that it'll increase your productivity exponentially, and allow you to created full fledged web applications with minimal......一起来看看 《Head First Rails》 这本书的介绍吧!