最近,我将一个项目的代码从 python 迁移到 golang,并且将 DB 从 MySQL 迁移到 ES。语言从 python 迁移到 golang 没有太大的意见,主要是这个项目对并发性和实时性要求确实高,处于对 Python 的担忧,所以这次该用 golang 编写,事实上,确实简便性不减,而且效率提高了。还有就是为啥将 DB 从 MySQL 迁移到 ES呢,这个值得说一下,我主要的考虑有以下几点:
- 操作基本都是查询,对查询要求高,而且查询不只是依赖于主键,可能用来查询的字段较多
- 数据量比较大,轻则几十G,以后会量级的增长
- 查询性能要求高,快的需要在百毫秒内完成,慢的也不能超过一秒
所以,根据目前团队的能力水平和已有架构,我们选择了 ElasticSearch 这个数据库(我们认为是数据库)。下面就介绍一下如何在 Ubuntu 上安装 ES,以及如何使用 golang 对 ES 进行一些常见的操作。
ES 安装
在 Ubuntu 中安装 ElasticSearch 将是一件非常简单的事情,首先,我们需要知道 ES 是跑在 JVM 上的,所以 JVM 是必须安装的,其实不用安装整套 JDK,安装个 JRE 就够了。然后再安装 ES。这里我为了方便,直接将 ES 安装成系统服务了,这样管理 ES 就方便多了。
咱们根据下面的命令走,想安装个 JDK8 先,因为 Oracle 对 Licence 的加强,现在都必须手动添加源了:
敲完之后,稍等片刻,JDK 应该就安装好啦,例如我这里验证了一下,是 OK 的。。
图 2:Java 版本 |
接下来是时候安装 ES 啦,为了方便,我还是使用 Ubuntu 的包安装方式安装,如果你喜欢更贱的方式的话,那么之前我写过一篇用 Docker 安装 ES 的文章 - 体验ELK,有兴趣的同学可以看看,想从新安装的话就 follow me:
将 Elasticsearch 的公开 GPG key 添加到 apt 中:
$ # https://liuliqiang.info
$ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
添加 Elasticsearch 的源:
$ echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
更新包数据库
$ sudo apt-get update
是时候安装 ES 啦,直接敲这个命令
$ sudo apt-get -y install elasticsearch
现在 ES 是算安装好了,然后我们配置一下 ES,打开
/etc/elasticsearch/elasticsearch.yml
这个文件,我们做一下这些配置:启动 ES
$ sudo service elasticsearch restart
设置 ES 的自启动
$ sudo update-rc.d elasticsearch defaults 95 10
验证一下 ES 是否启动正常
All right, 现在一切都就绪,是时候尝试一下用代码来操作 ES 啦!
Golang 操作 ElasticSearch
在 Golang 中连接 ES 的库不少,但是当前流行的不多,甚至说有没有流行的都难以界定。因为以 Github 的关注度来说,最高的 olivere/elastic 也只有 1257 个星,这在开源库中算是比较少的了,所以是不是流行还需判定。
但是,不能因为少就不用,我尝试过 3 个开源库,发现这款 olivere/elastic 还是可以的,有一定的弹性,功能也还行,所以本文就以这款开源库为连接库,进行演示 ES 的常见操作,下面就开始实操:
安装 olivere/elastic
安装库在 Golang 中还是很简单的事情,但是,你要想管理得好还是需要一些工具支持,这里也不搞那么麻烦了,直接来最简单的
go get
,因为我用的是 ES1.7.x,所以安装的是 v2 版本:$ go get gopkg.in/olivere/elastic.v2
连接 ES
要想操作 ES,那么肯定是得连接 ES 的,在 Golang 里连接 ES 有几种方法,这里介绍几种不同的方法:
默认的 ip 和 port,无密码验证
import (
elastic "gopkg.in/olivere/elastic.v2"
)
// Create a client @ liuliqiang.info
client, err := elastic.NewClient()
if err != nil {
fmt.Println("connect es error")
}
多 URL 连接
import (
elastic "gopkg.in/olivere/elastic.v2"
)
client, err := NewClient(SetSniff(false), SetURL("http://localhost:9200", "http://localhost:9201"))
if err != nil {
t.Fatal(err)
}
带验证连接
client, err := NewClient(SetBasicAuth("user", "secret"))
if err != nil {
t.Fatal(err)
}
操作ES
获得 ES 的连接之后,是时候来操作一下 ES 啦!
插入数据
这里需要说明一下,在 ES 里面没有 DB 和 Table 的概念,如果要说有的话,相近的概念映射如下:
并且 ES 是不需要先建表 和 Table Schema 的,下面就举一个插入一条数据的例子:
// Add a document to the index @ liuliqiang.info
tweet := Tweet{User: "olivere", Message: "Take Five"}
_, err = client.Index().
Index("twitter").
Type("tweet").
Id("1").
BodyJson(tweet).
Do()
if err != nil {
// Handle error
panic(err)
}
查找插入的数据
// Search with a term query
termQuery := elastic.NewTermQuery("user", "olivere")
searchResult, err := client.Search().
Index("twitter"). // search in index "twitter"
Query(&termQuery). // specify the query
Sort("user", true). // sort by "user" field, ascending
From(0).Size(10). // take documents 0-9
Pretty(true). // pretty print request and response JSON
Do() // execute
if err != nil {
// Handle error
panic(err)
}
就是这么简单的一个步骤,我们就完成了 golang 的 ES 操作了,关于更多的操作,我们可以参考后面的参考资料进行深入了解。