ElasticSearch第4篇(億級中文數(shù)據(jù)量 ElasticSearch與Sphinx建索引速度吻谋、查詢速度忠蝗、并發(fā)性能、實測對比)

經過實測:1.09億的數(shù)據(jù)量進行中文檢索漓拾。ElasticSearch單機的檢索性能在0.005~5.6秒之間阁最,此檢索速度可滿足95%的業(yè)務場景(注意:每條ES文檔平均65個漢字,數(shù)據(jù)源取自幾千本小說骇两,大部分文檔在15~300個漢字之間速种,不然字數(shù)太多索引太大電腦存不下)。

前置文章

由于本文章的前置操作強依賴于另一篇文章低千,推薦閱讀:
萬字詳解PHP+Sphinx中文億級數(shù)據(jù)全文檢索實戰(zhàn)(實測億級數(shù)據(jù)0.1秒搜索耗時)

運行配置

和Sphinx環(huán)境保持一致配阵。
服務器配置:CentOS7.6 16核4G內存。固態(tài)硬盤示血。
ES配置:ElasticSearch 8.14.1單機棋傍,默認配置,使用IK分詞器的ik_max_word配置难审。不設置分片和副本數(shù)量瘫拣。

數(shù)據(jù)準備

和Sphinx用的數(shù)據(jù)源保持一致。
依舊是上次用的幾千本小說告喊,整合后的單個txt文件9.57個G拂铡,用\n間隔,作為一個ES文檔葱绒。
數(shù)據(jù)量為109 450 000條數(shù)據(jù)。

數(shù)據(jù)插入

  • 創(chuàng)建索引與映射斗锭,并修改max_result_window參數(shù)
$params = [
    'index' => 'performance_test',
    'body'  => [
        'settings' => [
            'analysis' => [
                'analyzer' => [
                    'ik_analyzer' => [
                        'type'      => 'ik_max_word',
                    ],
                ],
            ],
        ],
        'mappings' => [
            'properties' => [
                'id' => [
                    'type'     => 'integer',
                ],
                'content' => [
                    'type'     => 'text',
                    'analyzer' => 'ik_analyzer',
                ],
            ],
        ],
    ],
];

$response = $client->indices()->create($params);
dd($response->asBool());


$params = [
    'index' => 'performance_test',
    'body'  => [
        'index' => [
            'max_result_window' => 2147483647 //用于控制在搜索查詢中可以檢索到的最大文檔數(shù)地淀,有符號int類型,最大可設置2^31 - 1,大了會有性能問題
        ]
    ]
];

$response = $client->indices()->putSettings($params);
dd($response->asBool());
  • 插入數(shù)據(jù)
//這段代碼只確贬牵可批量插入帮毁,忽略精準的數(shù)據(jù)處理高可用問題实苞。
$start = microtime(true);
ini_set('memory_limit', '4096M');
set_time_limit(0);

include __DIR__ . './vendor/autoload.php';

$client = \Elasticsearch\ClientBuilder::create()->setHosts(['192.168.0.183:9200'])
    ->setBasicAuthentication('elastic', '123456')->build();


/**
 * @function 逐行讀取大文件
 * @param    $file_name string 文件名
 * @return   Generator|object
 */
function readLargeFile($file_name) {
    $file = fopen($file_name, 'rb');
    if (! $file) {
        return false;
    }

    while (! feof($file)) {
        $line = fgets($file);
        if ($line !== false) {
            yield $line;
        }
    }

    fclose($file);
}


// 使用生成器逐行讀取大文件
$file_resource = readLargeFile('E:/其它/一億行漢字文本.txt');
foreach ($file_resource as $loop => $line) {
    $loop ++;
    $from_charset = mb_detect_encoding($line, 'UTF-8, GBK, GB2312, BIG5, CP936, ASCII');
    $utf8_str     = @iconv($from_charset, 'UTF-8', $line);
    if(in_array($utf8_str, ["\n", "\r", "\n\r", "\r\n"])) {
        continue;
    }


    $params['body'][] = ['index' => ['_index' => 'performance_test', '_id' => $loop]];
    $params['body'][] = ['id' => $loop, 'content' => $utf8_str];


    if(count($params['body']) >= 100000) {
        $client->bulk($params); //忽略批量插入的錯誤
        $params = [];
    }
}

echo '插入耗時:' . bcsub(microtime(true), $start, 3) . '秒';

實測ES與Sphinx新增數(shù)據(jù)建索引速度對比

應用 耗時 新增數(shù)據(jù)量 補充
Sphinx 50.5分鐘 109 450 000 /
ElasticSearch 119分鐘 109 450 000 (總時間 - PHP代碼執(zhí)行時間,總耗時190分鐘)

實測ES與Sphinx查詢性能對比

某些項烈疚,ElasticSearch搜索出來的結果遠超MySQL和Sphinx查詢的結果黔牵,這是分詞匯總的緣故。
而Sphinx使用的是SPH_MATCH_PHRASE格式爷肝,所以數(shù)量不會有ES那么多猾浦,若用SPH_MATCH_ANY,可能有更多的檢索結果灯抛。

類型 搜索關鍵字 Sphinx搜索耗時(秒) ES搜索耗時(秒) MySQL搜索耗時(秒) Sphinx搜索數(shù)量 ES搜索數(shù)量 MySQL搜索數(shù)量
數(shù)字 123 0.005 0.005 305.142 3121 3877 8143
中文單字 0.013 0.115 223.184 67802 60016 103272
英文單字母 A 0.031 0.009 339.576 136428 0 1017983
單中文標點 金赦。 4.471 0.003 125.106 67088012 0 67096182
單英文標點 . 0 0.003 251.171 0 0 6697242
可打印特殊字符 ? 0 0.002 355.469 0 0 0
中文詞語(易分詞) 黑色衣服 0.066 0.283 346.442 1039 722402 1062
中文詞語(不易分詞) 夏威夷 0.011 0.114 127.054 3636 3664 3664
中文詞語(熱門) 你好 0.022 0.091 126.979 102826 136996 137717
中文詞語(冷門) 旖旎 0.010 0.077 345.493 4452 4496 4528
英文單詞 good 0.010 0.074 137.562 553 588 1036
中文短語 他不禁一臉茫然 1.742 0.973 218.272 0 49698660 0
英文短語 I am very happy 0.015 0.121 355.235 1 48375 0
長文本 陳大人不急著回答,他先從柜臺下面又抽出了一份文案对嚼,翻了好一陣之后才回答道:“瞧夹抗,果然如此,如今廣州這邊官職該放得都放出去了纵竖,只剩下消防營山字營的一個哨官之職漠烧。不出所料的話,督撫大人準會委你這個職務靡砌。 0.131 5.638 129.204 1 80498922 1

實測ES與Sphinx并發(fā)性能對比

  • 壓測方式 :ab -c 1 -n 10~1000 127.0.0.1/temp/es/test.php
  • 中文定值關鍵字為華盛頓已脓,英文定值關鍵字為XYZ,30位隨機中文或英文字符乏奥,由代碼生成(用代碼生成數(shù)據(jù)源摆舟,是避免引入更好的數(shù)據(jù)源帶來了性能誤差)。
  • 由于ES IK分詞器比Sphinx中文分詞器分詞粒度更細邓了,所以并發(fā)下30位隨機中文字符檢索性能極具下降恨诱。
生成任意正整數(shù)個中文字符
function generateRandomChinese($length) {
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= mb_convert_encoding('&#' . mt_rand(0x3e00, 0x9fa5) . ';', 'UTF-8', 'HTML-ENTITIES');
    }
    return $result;
}

生成任意正整數(shù)個英文字符
function generateRandomEnglish($length) {
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= chr(mt_rand(97, 122)); // 小寫字母ASCII碼范圍: 97~122;大寫字母:65~90
    }
    return $result;
}
類型 搜索次數(shù)(ab -n 參數(shù)值) Sphinx耗時(秒) ES耗時(秒)
固定中文多次搜索 10 0.256 0.623
固定中文多次搜索 100 1.435 1.915
固定中文多次搜索 1000 11.604 18.821
隨機30位中文字符多次搜索 10 0.517 4.257
隨機30位中文字符多次搜索 100 2.305 52.505
隨機30位中文字符多次搜索 1000 17.197 超時
固定英文多次搜索 10 0.327 0.584 0.584
固定英文多次搜索 100 0.747 5.085
固定英文多次搜索 1000 8.510 50.423
隨機30位英文字符多次搜索 10 0.077 0.0623
隨機30位英文字符多次搜索 100 0.766 4.810
隨機30位英文字符多次搜索 1000 9.428 50.698

ES與Sphinx各項優(yōu)缺點直觀對比

項目 ElasticSearch(相比于Sphinx) Sphinx(相比于ElasticSearch)
創(chuàng)建索引性能
查詢性能 相差無幾 相差無幾
并發(fā)性能
中文分詞支持 需安裝IK分詞器 需安裝Mmseg分詞工具和Coreseek中文搜索引擎框架
實時搜索 友好 不友好
對增量數(shù)據(jù)(Insert) 通過代碼層可直接同步ES 需要運維層面的觸發(fā)而生成增量索引
與數(shù)據(jù)庫一致性同步問題(Update骗炉、Delete) ES支持直接更新 Sphinx不支持對索引更新照宝,需重建索引
客戶端語言支持 Java、PHP句葵、JavaScript厕鹃、Perl、Ruby乍丈、Python剂碴、Golang、Eland轻专、.NET忆矛、Rust Java、PHP、Python催训、Perl洽议、C
開發(fā)語言 Java C++
支持跨平臺
架構 C/S C/S
合作流程 內置數(shù)據(jù)庫,支持對自身數(shù)據(jù)進行復雜的增刪改查漫拭,但需要MySQL兜底 內置索引庫亚兄、幫MySQL找ID
事務支持 不支持 不支持
系統(tǒng)內存占用
集群部署 支持 支持
集群協(xié)調模式 自動負載均衡 節(jié)點間協(xié)調 需要手動設置負載均衡和協(xié)調
數(shù)據(jù)分析 內建強大的聚合和分析功能 不支持復雜的數(shù)據(jù)分析
GUI 需額外安裝組件,例如Kibana 無官方可視化工具
生態(tài) 繁榮 一般
上手難度
安全性 支持基于用戶的訪問控制采驻,集成X-Pack進行高級安全配置审胚。但內部的Log4j2組件存在高危漏洞 基本的權限管理,需依賴外部工具
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末挑宠,一起剝皮案震驚了整個濱河市菲盾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌各淀,老刑警劉巖懒鉴,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碎浇,居然都是意外死亡临谱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門奴璃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悉默,“玉大人,你說我怎么就攤上這事苟穆〕危” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵雳旅,是天一觀的道長跟磨。 經常有香客問我,道長攒盈,這世上最難降的妖魔是什么抵拘? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮型豁,結果婚禮上僵蛛,老公的妹妹穿的比我還像新娘。我一直安慰自己迎变,他們只是感情好充尉,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衣形,像睡著了一般驼侠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天泪电,我揣著相機與錄音,去河邊找鬼纪铺。 笑死相速,一個胖子當著我的面吹牛,可吹牛的內容都是我干的鲜锚。 我是一名探鬼主播突诬,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼芜繁!你這毒婦竟也來了旺隙?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤骏令,失蹤者是張志新(化名)和其女友劉穎蔬捷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榔袋,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡周拐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了凰兑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妥粟。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吏够,靈堂內的尸體忽然破棺而出勾给,到底是詐尸還是另有隱情,我是刑警寧澤锅知,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布播急,位于F島的核電站,受9級特大地震影響喉镰,放射性物質發(fā)生泄漏旅择。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一侣姆、第九天 我趴在偏房一處隱蔽的房頂上張望生真。 院中可真熱鬧,春花似錦捺宗、人聲如沸柱蟀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽长已。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間术瓮,已是汗流浹背康聂。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胞四,地道東北人恬汁。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像辜伟,于是被迫代替她去往敵國和親氓侧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容