31

Go: ElasticSearch客户端学习

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=Mzg2NTA2NzQ2Nw%3D%3D&%3Bmid=2247483978&%3Bidx=1&%3Bsn=e3ba046a588f699a0d62e66ce33d0d2c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

选择程序包来消费ElasticSearch是进行项目的第一步。如果ElasticSearch是工作流的重要组成部分,则此选择可能会影响应用程序的性能。但是,对于Go的选择很少:最著名的是olivere/elastic ,而官方的则是elastic/go-elasticsearch 。让我们回顾一下每个程序包的优缺点。

设计

两个程序包的设计截然不同,让我们通过一个query来观察它们的不同之处。

mInuymN.png!mobile

olivere/elastic 提供了完整的查询DSL,可以完全抽象真实的查询。这是内置的查询:

7BFFzyf.png!mobile

这是官方包的内置查询方式:

u2i6nem.png!mobile

这种查询更加详细明确。用Go中的map方式转化原始的json查询语句。

这两种设计都可以满足不同的开发者。不关心具体查询的开发者倾向于第一种,同时希望知道明确查询细节的更愿意选择第二种。现在让我们回顾下这两种方式的性能表现。

基准测试

在样例中,我们构建一个简单结构来存储和索引查询。这是一个示例文档:

J7ZvMf6.png!mobile

使用的查询是上一节介绍的查询。基准测试将涵盖:

  • 查询的建立

  • 结果解码

这是结果:

olivere/elastic:
name time/op
QuerySearch-4 4.14ms ± 5%
name alloc/op
QuerySearch-4 160kB ± 1%
name allocs/op
QuerySearch-4 1.65k ± 0%

official client:
name time/op
QuerySearch-4 3.88ms ± 5%
name alloc/op
QuerySearch-4 118kB ± 0%
name allocs/op
QuerySearch-4 514 ± 0%

官方包更加高效分配的内存更少,给应用程序带来更好性能的同时也能降低gc的频率。

优化

优化的第一步是分析。让我们在 olivere/elastic 基准测试中运行pprof。这里是内存分配对象top5的方法:

Showing top 5 nodes out of 47
flat% sum%
29.83% 29.83% reflect.New
29.43% 59.26% encoding/json.(*decodeState).literalStore
8.41% 67.66% encoding/json.(*decodeState).object
8.15% 75.82% encoding/json.Unmarshal
5.61% 81.42% encoding/json.(*RawMessage).UnmarshalJSON

encoding/json解码阶段占据了超过80%的分配。

BBvaqaI.png!mobile

第一个可行的优化方法是替换json解码器为easyjson

eUv2Aze.png!mobile

再次运行基准测试将稍微改善分配数量(-12%):

olivere/elastic:
name old time/op new time/op delta
QuerySearch-4 4.14ms ± 5% 4.12ms ± 7% ~
name old alloc/op new alloc/op delta
QuerySearch-4 160kB ± 1% 158kB ± 1% -1.57%
name old allocs/op new allocs/op delta
QuerySearch-4 1.65k ± 0% 1.45k ± 0% -12.15%

现在这部分已经优化了,我们可以再次运行pprof来看看是否还有更多低挂的水果。pprof让我们使用以下命令删除已经检查过的路径:go tool pprof -alloc_objects  -hide =” decodeState | .UnmarshalJSON | Unmarshal | Decode”  mem.out:

qy2eaiq.png!mobile

现在查询的创建占据最多的分配。olivere/elastic提供了Source()方法允许直接以字符串的方式发送查询。这是优化后的结果:

name                    time/op
QuerySearch-4 4.12ms ± 5%
OptimizedQuerySearch-4 4.07ms ± 4%
name alloc/op
QuerySearch-4 158kB ± 1%
OptimizedQuerySearch-4 152kB ± 1%
name allocs/op
QuerySearch-4 1.45k ± 0%
OptimizedQuerySearch-4 1.35k ± 0%

至此我们可以通过优化得到一些改善,但仍然和官方包相较甚远。

编译自:

https://medium.com/a-journey-with-go/go-elasticsearch-clients-study-case-dbaee1e02c7

博客地址:

https://www.chenjie.info/2592

rmErYvQ.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK