昨天的帖子: https://www.v2ex.com/t/410623 , 先来讲一下历程,mysql 共 30 个字段,一个 article 主字段,其余 29 个字段都是机器翻译改文章的内容,最初用的 xunsearch 索引 50 万数据,查询时间在 1 秒徘徊,太慢,用 elasticsearch 索引这 50 万行数据,还是 1 秒左右徘徊,想到 ES 默认内存是 1G,于是扩充到 9G (服务器 i5+16G+2T HDD ),这下好了单次查询时间,试了很多次,都在 5 秒以上,哪怕我搜索一个单字段而不是搜索所有字段,比如:article_cn 这个字段,还是 5 秒,好的时候 3 秒或者 2 秒
我当时在想,9 个 G 也够把所有数据存到内存中了吧,结果现实还是很骨感,ES 可不可以把所有数据都存到内存中?
而且我发现 ES 一个奇怪的特点,就是有一个冷却期,如果你短时间频繁的搜索各种不同的关键词,query 时间会慢慢减少,如果你很久不搜索,再次搜索时,query 时间会很长。昨晚我试了很多次,逐渐降低到 1s 之内,今早一起来,query 时间又恢复到 8 秒了。。。
1
yonka 2017-12-01 11:00:08 +08:00
IO 负担过重?
|
2
dangyuluo 2017-12-01 11:10:03 +08:00
贴 mapping 啊
|
3
Reign OP @dangyuluo
'mappings' => [ 'blog' => [ 'properties' => [ 'article_en' => [ 'type'=>'text', 'analyzer'=>'english' ], 'article_zh' => [ 'type'=>'text', 'analyzer'=>'ik_max_word' ], 'article_ru' => [ 'type'=>'text', 'analyzer'=>'russian', ], 'article_ja' => [ 'type'=>'text', 'analyzer'=>'kuromoji', ], 'article_de' => [ 'type'=>'text', 'analyzer'=>'german', ], 'article_es' => [ 'type'=>'text', 'analyzer'=>'spanish', ], 'article_fr' => [ 'type'=>'text', 'analyzer'=>'french', ], 'article_pt' => [ 'type'=>'text', 'analyzer'=>'portuguese', ], 'article_it' => [ 'type'=>'text', 'analyzer'=>'italian', ], 'article_pl' => [ 'type'=>'text', 'analyzer'=>'polish', ], 'article_tr' => [ 'type'=>'text', 'analyzer'=>'turkish', ], 'article_nl' => [ 'type'=>'text', 'analyzer'=>'dutch', ], 'article_ko' => [ 'type'=>'text', 'analyzer'=>'openkoreantext-analyzer', ], 'article_cs' => [ 'type'=>'text', 'analyzer'=>'czech', ], 'article_ar' => [ 'type'=>'text', 'analyzer'=>'arabic', ], 'article_vi' => [ 'type'=>'text', ], 'article_id' => [ 'type'=>'text', 'analyzer'=>'indonesian', ], 'article_no' => [ 'type'=>'text', 'analyzer'=>'norwegian', ], 'article_el' => [ 'type'=>'text', 'analyzer'=>'greek', ], 'article_sv' => [ 'type'=>'text', 'analyzer'=>'swedish', ], 'article_ro' => [ 'type'=>'text', 'analyzer'=>'romanian', ], 'article_hu' => [ 'type'=>'text', 'analyzer'=>'hungarian', ], 'article_da' => [ 'type'=>'text', 'analyzer'=>'danish', ], 'article_th' => [ 'type'=>'text', 'analyzer'=>'thai', ], 'article_sk' => [ 'type'=>'text', ], 'article_fi' => [ 'type'=>'text', 'analyzer'=>'finnish', ], 'article_bg' => [ 'type'=>'text', 'analyzer'=>'bulgarian', ], 'article_he' => [ 'type'=>'text', ], 'article_lt' => [ 'type'=>'text', 'analyzer'=>'lithuanian', ], 'article_uk' => [ 'type'=>'text', 'analyzer'=>'ukrainian', ], 'article_hr' => [ 'type'=>'text', ], 'article_sr' => [ 'type'=>'text', ], 'article_ca' => [ 'type'=>'text', 'analyzer'=>'catalan', ], 'article_sl' => [ 'type'=>'text', ], 'article_lt' => [ 'type'=>'text', 'analyzer'=>'latvian', ], 'article_es' => [ 'type'=>'text' ], ] ] ] |
4
Reign OP 搜索:
$params = [ 'index' => 'blahblah', 'type' => 'blog', 'body' => [ 'from'=>$page, 'size'=>30, 'query' => [ 'query_string'=> [ 'query'=>$item, "default_operator"=>"AND" ] ] ] ]; |
5
janxin 2017-12-01 11:18:04 +08:00
es 要改配置的,配置是不是默认的?
|
6
owenliang 2017-12-01 11:19:13 +08:00 1
小伙子工作全靠猜啊。
vmstat, iostat, top, mpstat 分析分析瓶颈啊? |
7
Reign OP @janxin 只改了内存为 9G
ps aux | grep elasticsearch elastic+ 4268 1.8 62.8 19521528 10358908 ? Ssl 10:15 1:09 /bin/java -Xms9g -Xmx9g |
8
dangyuluo 2017-12-01 11:31:44 +08:00
我猜,你用这么多分词器,每一次搜索都要初始化这些分词器然后对你的搜索语句进行分词,可能在这里耗时间比较多。
你可以试验一下几个分词器的时间。这种情况我觉得可以考虑把不同的语言放在不同的 nodes 上 |
9
bzzhou 2017-12-01 13:19:00 +08:00
小伙子,好好定性定量分析一下,说不定问题早就解决了
|
11
JohnSmith 2017-12-01 14:20:29 +08:00 via Android
@bzzhou +1
利用工具定位问题比代码能力重要,现在提个 issue 都会要求贴环境和日志的 |
12
jowuIM 2017-12-01 14:38:44 +08:00
变慢应该是冷启动命中问题,不太熟悉 es,但是应该能用日志把一些热词装进内存
|
13
armstrong 2017-12-01 14:45:19 +08:00
我没记错的话,官方推荐的 ES 配置内存是 16GB,现在业界用 ES 的公司和 Team 多了去了,都用着很开心,为啥你怨气这么多呢
|
14
zhengxiaowai 2017-12-01 15:37:19 +08:00
明显是你对 ES 不熟悉啊,多去看看手册吧,你这全靠猜啊。。。。
|
15
gouchaoer 2017-12-01 15:40:23 +08:00 6
lz 的做法是对的,如果 lz 问个问题:为啥我的 es 这么慢,有大神帮忙看看么?
估计没人理他 然后 lz 出来大骂 es 垃圾,如果我用 xunsearch 的话速度还比这更快,然后就一堆人出来说: 你这个 mapping 这样写 balabala 就 ok 了,然后 lz 问题解决了 |
16
misaka19000 2017-12-01 15:44:37 +08:00
|
18
anofac 2017-12-01 16:02:42 +08:00 via Android
虽然我没实际用过 ES,不过有看过一点官方文档。LZ 这加了 ES 内存反倒慢了,让我忽然想到,ES 底层是 Lucene 呀,真正大部分查询的活儿是 Lucene 在干,你把 ES 内存调那么高, Lucene 表示被压榨了,不开心。。。 不知道说的对不对,如有错误请真正的大神指正:)
|
20
sampeng 2017-12-01 16:16:38 +08:00
内存不是核心问题。。。曾经一个 case。就算内存加到 64G 页没什么卵用。index 和分词没搞好,都是浮云。我也没用工具测。只是一眼就看出 jvm 的内存有多少吃多少,就算加到天际又又何用
主要是 mapping。mapping 搞太多分词了。。如果只用一个分词先试一下。如果没问题,那就针对这个问题去解决。 个人猜想可以冗余存储。每个语法一个 index。这样会不会快很多。在一个索引下创建 n 个分词器进行分词处理。这个 index 会不会膨胀的太厉害? |
21
Livid MOD |
23
lyc1116 2017-12-01 16:29:40 +08:00
es 索引用的是堆外内存, 尽量少给 JVM 分配内存。 另外可以在启动时开启 preload,会把索引 mmap 到物理内存里。
|
25
est 2017-12-01 16:43:51 +08:00
不开个 64G 内存你敢用 ES ?
|
27
st2udio 2017-12-01 17:13:58 +08:00
我们 ES 用了 5 台 48 核心 128G 的机器。。
|
29
Tinngi 2017-12-01 17:51:50 +08:00
看看是不是 GC 问题。
@vus520 如果不是 term 或者 fuzzy 这样的底层搜索,都需要分词的。search analyzer 就是用来指定搜索的分词器。 |
30
amd00 2017-12-01 18:56:56 +08:00
这个问题你 4g 内存比 9g 内存性能高其实可以参考这个地方 https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html#_give_less_than_half_your_memory_to_lucene @Reign 只给系统的一半,也就是你占用 mysql 5g 剩下 11g 分一半给 elasticsearch 性能比 11g 都分给 elasticsearch 高
|
31
zuo 2017-12-02 04:41:00 +08:00
为了获取更好的性能,通常 elasticsearch 会建议留一半的内存给 Lucene 做 cache,这样就可以将数据 mapping 到内存中,避免 search 的时候产生 I/O
|
35
ewBuyVmLZMZE 2017-12-03 05:31:02 +08:00 via iPhone
内存全给 ES,没有剩余内存给 Lucese,能快么? ES 只是壳,主要是集群之类的特性,你不能把内存全分配了,至少留一半给 Lucense
|
37
512557852 2017-12-03 16:03:48 +08:00
@aiyo218 确切的说在 java 1.8 中,使用 CMS 是 32766MB,G1 是 32736M,比 32G 少一点。
|
38
fatpa 2017-12-04 00:18:43 +08:00
@Livid 曾为了扛下时延 10s 内大概 1000w 每分钟的数据量,堆了 10 来台 128G 的 ssd 集群,特别难过
|
39
hayao650 2018-03-06 09:09:57 +08:00
|
40
wukairobin 2018-06-19 17:07:47 +08:00
并不是越大越好,因为 lucene 也是要吃内存的 你一点不留给 lucene,意味着全文索引很慢很慢
|