内容简介:近期,笔者在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的对比思考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
编译原理
Alfred V.Aho、Jeffrey D.Ullman、Ravi Sethi / 李建中 / 机械工业出版社 / 2003-8 / 55.00元
《编译原理》作者Alfred V.Aho、Ravi Sethi和Jeffrey D.Ullman是世界著名的计算机 科学家,他们在计算机科学理论、数据库等很多领域都做出了杰出贡献。《编译原理》 是编译领域无可替代的经典著作,被广大计算机专业人士誉为“龙书”。《编译原理》一 直被世界各地的著名高等院校和科研机构(如贝尔实验室、哥伦比亚大学、普 林斯顿大学和斯坦福大学等)广泛用作本科生和研究生编译原理......一起来看看 《编译原理》 这本书的介绍吧!