ElasticSearch第4篇(億級中文數據量 ElasticSearch與Sphinx建索引速度、查詢速度、併發性能、實測對比)

来源:https://www.cnblogs.com/phpphp/p/18327906
-Advertisement-
Play Games

經過實測:1.09億的數據量進行中文檢索。ElasticSearch單機的檢索性能在0.005~5.6秒之間,此檢索速度可滿足95%的業務場景(註意:每條ES文檔平均65個漢字,數據源取自幾千本小說,大部分文檔在15~300個漢字之間,不然字數太多索引太大電腦存不下)。 前置文章 由於本文章的前置操 ...


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

前置文章

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

運行配置

和Sphinx環境保持一致。
伺服器配置:CentOS7.6 16核4G記憶體。固態硬碟。
ES配置:ElasticSearch 8.14.1單機,預設配置,使用IK分詞器的ik_max_word配置。不設置分片和副本數量。

數據準備

和Sphinx用的數據源保持一致。
依舊是上次用的幾千本小說,整合後的單個txt文件9.57個G,用\n間隔,作為一個ES文檔。
數據量為109 450 000條數據。

數據插入

  • 創建索引與映射,並修改max_result_window參數
$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 //用於控制在搜索查詢中可以檢索到的最大文檔數,有符號int類型,最大可設置2^31 - 1,大了會有性能問題
        ]
    ]
];

$response = $client->indices()->putSettings($params);
dd($response->asBool());
  • 插入數據
//這段代碼只確保可批量插入,忽略精準的數據處理高可用問題。
$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新增數據建索引速度對比

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

實測ES與Sphinx查詢性能對比

某些項,ElasticSearch搜索出來的結果遠超MySQL和Sphinx查詢的結果,這是分辭彙總的緣故。
而Sphinx使用的是SPH_MATCH_PHRASE格式,所以數量不會有ES那麼多,若用SPH_MATCH_ANY,可能有更多的檢索結果。

類型 搜索關鍵字 Sphinx搜索耗時(秒) ES搜索耗時(秒) MySQL搜索耗時(秒) Sphinx搜索數量 ES搜索數量 MySQL搜索數量
數字 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併發性能對比

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

生成任意正整數個英文字元
function generateRandomEnglish($length) {
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= chr(mt_rand(97, 122)); // 小寫字母ASCII碼範圍: 97~122;大寫字母:65~90
    }
    return $result;
}
類型 搜索次數(ab -n 參數值) 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
固定英文多次搜索 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各項優缺點直觀對比

項目 ElasticSearch(相比於Sphinx) Sphinx(相比於ElasticSearch)
創建索引性能
查詢性能 相差無幾 相差無幾
併發性能
中文分詞支持 需安裝IK分詞器 需安裝Mmseg分詞工具和Coreseek中文搜索引擎框架
實時搜索 友好 不友好
對增量數據(Insert) 通過代碼層可直接同步ES 需要運維層面的觸發而生成增量索引
與資料庫一致性同步問題(Update、Delete) ES支持直接更新 Sphinx不支持對索引更新,需重建索引
客戶端語言支持 Java、PHP、JavaScript、Perl、Ruby、Python、Golang、Eland、.NET、Rust Java、PHP、Python、Perl、C
開發語言 Java C++
支持跨平臺
架構 C/S C/S
合作流程 內置資料庫,支持對自身數據進行複雜的增刪改查,但需要MySQL兜底 內置索引庫、幫MySQL找ID
事務支持 不支持 不支持
系統記憶體占用
集群部署 支持 支持
集群協調模式 自動負載均衡 節點間協調 需要手動設置負載均衡和協調
數據分析 內建強大的聚合和分析功能 不支持複雜的數據分析
GUI 需額外安裝組件,例如Kibana 無官方可視化工具
生態 繁榮 一般
上手難度
安全性 支持基於用戶的訪問控制,集成X-Pack進行高級安全配置。但內部的Log4j2組件存在高危漏洞 基本的許可權管理,需依賴外部工具

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本節內容 因為risc-v存在硬體特權級機制,我們又要實現一個可以使得應用程式工作在用戶級,使得操作系統工作在特權級.原因是要保證用戶態的應用程式不能隨意使用內核態的指令,要使用內核態的指令就必須通過操作系統來執行,這樣有了操作系統的控制和檢查,程式不會因為應用程式的問題導致整個操作系統都運行錯誤. ...
  • 本章將和大家分享Linux中的許可權控制。廢話不多說,下麵我們直接進入主題。 一、基礎知識 Linux作為一種多用戶的操作系統(伺服器系統),允許多個用戶同時登陸到系統上,並響應每個用戶的請求。 任何需要使用操作系統的用戶,都需要一個系統賬號,賬號分為:管理員賬號與普通用戶賬號。 在Linux中,操作 ...
  • 在現代軟體開發和部署中,Docker容器已成為一種流行的技術。然而,隨著容器的廣泛使用,數據保護和遷移也變得至關重要。本文將詳細介紹如何備份和遷移Docker容器,確保你的應用和數據在任何時候都是安全的。 一、為什麼需要備份和遷移Docker容器? 在某些情況下,你可能需要備份和遷移Docker容器 ...
  • 書接上文,在一個正常的事務複製環境中,如果發生了資料庫還原,事務複製會不會出問題,出問題之後又如何恢復,如果在不刪除訂閱發佈重建的情況下,如何在現有基礎上修複事務複製的異常,這個問題可以分為兩部分看: 1,如果publisher資料庫發生了還原操作,事務複製會出現什麼異常,該如何恢復? 2,如果是s ...
  • Vue 的 Keep-Alive 組件是用於緩存組件的高階組件,可以有效地提高應用性能。它能夠使組件在切換時仍能保留原有的狀態信息,並且有專門的生命周期方便去做額外的處理。該組件在很多場景非常有用,比如: · tabs 緩存頁面 · 分步表單 · 路由緩存 在 Vue 中,通過 KeepAlive ...
  • 上次向大家分享了論文圖譜項目Awesome-Graphs的介紹文章,這次我們就拿圖計算系統的奠基文章Pregel開篇,沿著論文圖譜的主線,對圖計算系統的論文內容進行解讀。 ...
  • 1. 事物的四大特性 事務是邏輯上的一組操作,要麼都執行,要麼都不執行 原子性(Atomicity):事務是最小的執行單位,不允許分割。事務的原子性確保動作要麼全部完成,要麼完全不起作用; 一致性(Consistency):執行事務前後,數據保持一致,例如轉賬業務中,無論事務是否成功,轉賬者和收款人 ...
  • GreatSQL 的刷新鎖 前言 因為運維小伙伴執行dump備份命令,導致資料庫卡住,很多會話都在waiting for table flush,基於這一故障,我對GreatSQL的刷新鎖進行了研究。感興趣的小伙伴請隨我一探究竟吧。 刷新鎖的癥狀 刷新鎖問題的主要癥狀是資料庫會進入嘎然而止的狀態,所 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...