最近,我将一个项目的代码从 python 迁移到 golang,并且将 DB 从 MySQL 迁移到 ES。语言从 python 迁移到 golang 没有太大的意见,主要是这个项目对并发性和实时性要求确实高,处于对 Python 的担忧,所以这次该用 golang 编写,事实上,确实简便性不减,而且效率提高了。还有就是为啥将 DB 从 MySQL 迁移到 ES呢,这个值得说一下,我主要的考虑有以下几点:

  1. 操作基本都是查询,对查询要求高,而且查询不只是依赖于主键,可能用来查询的字段较多
  2. 数据量比较大,轻则几十G,以后会量级的增长
  3. 查询性能要求高,快的需要在百毫秒内完成,慢的也不能超过一秒

所以,根据目前团队的能力水平和已有架构,我们选择了 ElasticSearch 这个数据库(我们认为是数据库)。下面就介绍一下如何在 Ubuntu 上安装 ES,以及如何使用 golang 对 ES 进行一些常见的操作。

ES 安装

在 Ubuntu 中安装 ElasticSearch 将是一件非常简单的事情,首先,我们需要知道 ES 是跑在 JVM 上的,所以 JVM 是必须安装的,其实不用安装整套 JDK,安装个 JRE 就够了。然后再安装 ES。这里我为了方便,直接将 ES 安装成系统服务了,这样管理 ES 就方便多了。

咱们根据下面的命令走,想安装个 JDK8 先,因为 Oracle 对 Licence 的加强,现在都必须手动添加源了:

$ sudo add-apt-repository -y ppa:webupd8team/java$ sudo apt-get update$ sudo apt-get -y install oracle-java8-installer# site: https://liuliqiang.info

敲完之后,稍等片刻,JDK 应该就安装好啦,例如我这里验证了一下,是 OK 的。。

java -version

接下来是时候安装 ES 啦,为了方便,我还是使用 Ubuntu 的包安装方式安装,如果你喜欢更贱的方式的话,那么之前我写过一篇用 Docker 安装 ES 的文章 - 体验ELK,有兴趣的同学可以看看,想从新安装的话就 follow me:

  1. 将 Elasticsearch 的公开 GPG key 添加到 apt 中:

     $ # https://liuliqiang.info
     $ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
  2. 添加 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
  3. 更新包数据库

     $ sudo apt-get update
  4. 是时候安装 ES 啦,直接敲这个命令

     $ sudo apt-get -y install elasticsearch
  5. 现在 ES 是算安装好了,然后我们配置一下 ES,打开 /etc/elasticsearch/elasticsearch.yml 这个文件,我们做一下这些配置:

  6. 启动 ES

     $ sudo service elasticsearch restart
  7. 设置 ES 的自启动

     $ sudo update-rc.d elasticsearch defaults 95 10
  8. 验证一下 ES 是否启动正常

All right, 现在一切都就绪,是时候尝试一下用代码来操作 ES 啦!

Golang 操作 ElasticSearch

在 Golang 中连接 ES 的库不少,但是当前流行的不多,甚至说有没有流行的都难以界定。因为以 Github 的关注度来说,最高的 olivere/elastic 也只有 1257 个星,这在开源库中算是比较少的了,所以是不是流行还需判定。

但是,不能因为少就不用,我尝试过 3 个开源库,发现这款 olivere/elastic 还是可以的,有一定的弹性,功能也还行,所以本文就以这款开源库为连接库,进行演示 ES 的常见操作,下面就开始实操:

  1. 安装 olivere/elastic

    安装库在 Golang 中还是很简单的事情,但是,你要想管理得好还是需要一些工具支持,这里也不搞那么麻烦了,直接来最简单的 go get,因为我用的是 ES1.7.x,所以安装的是 v2 版本:

     $ go get gopkg.in/olivere/elastic.v2
  2. 连接 ES

    要想操作 ES,那么肯定是得连接 ES 的,在 Golang 里连接 ES 有几种方法,这里介绍几种不同的方法:

    1. 默认的 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")
       }
    2. 多 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)
       }
    3. 带验证连接

       client, err := NewClient(SetBasicAuth("user", "secret"))
       if err != nil {
           t.Fatal(err)
       }
  3. 操作ES

    获得 ES 的连接之后,是时候来操作一下 ES 啦!

    1. 插入数据

      这里需要说明一下,在 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)
       }
    2. 查找插入的数据

       // 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 操作了,关于更多的操作,我们可以参考后面的参考资料进行深入了解。

Reference

  1. How To Install Elasticsearch, Logstash, and Kibana (ELK Stack) on Ubuntu 14.04
  2. Golang-Libraty: Elastic