docker安裝es及在laravel中的應(yīng)用

docker安裝elasticsearch

關(guān)于es的詳細(xì)介紹以及安裝包編譯安裝的方式搁进,可以看之前的文章:安裝Elasticsearch搜索引擎

這次換個花樣嗓违,使用docker(這里不解釋docker是什么了,不了解的自行百度)來安裝李破,直接開搞,操作如下

  1. 安裝docker

    # 安裝
    yum install -y docker
    # 查看版本信息
    docker version
    # 修改docker的鏡像源
    vim /etc/docker/daemon.json
    
    {
        "registry-mirrors": ["https://ftnejmh3.mirror.aliyuncs.com"]
    }
    
     # 啟動docker
    systemctl start docker
    # 停止docker
    systemctl stop docker
    # 查看docker狀態(tài)
    systemctl status docker
    # 重新啟動docker
    systemctl restart docker
    

    如果docker沒有命令自動補(bǔ)全功能,可以安裝如下

    yum -y install bash-completion
    source /usr/share/bash-completion/bash_completion
    
  2. 拉取es鏡像(文件有點大恐仑,需要一定時間)

    docker pull elasticsearch:7.12.1
    
  3. 在宿主機(jī)創(chuàng)建和容器內(nèi)共享的目錄

    # 存放配置文件目錄
    mkdir -p /docker/es/conf
    # 存放數(shù)據(jù)目錄
    mkdir -p /docker/es/data
    # 存放日志目錄
    mkdir -p /docker/es/logs
    # 存放插件目錄
    mkdir -p /docker/es/plugins
    # 創(chuàng)建好目錄后為了防止下邊創(chuàng)建容器報錯,給宿主機(jī)的這個es目錄賦個讀寫權(quán)限
    chmod -R 777 /docker/es/
    
  4. 創(chuàng)建es配置文件(參數(shù)意思不解釋为鳄,上方提到的文章內(nèi)有解釋)

    vi /docker/es/conf/elasticsearch.yml

    cluster.name: my-application 
    node.name: node-1 
    path.data: /usr/share/elasticsearch/data 
    path.logs: /usr/share/elasticsearch/logs
    network.host: 0.0.0.0
    http.port: 9200
    cluster.initial_master_nodes: ["node-1"]
    
  5. 構(gòu)建容器(構(gòu)建很快裳仆,但是容器內(nèi)es的啟動速度很慢,構(gòu)建完先耐心等待一下)

    docker run -p 9200:9200 -d --name es -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -v /docker/es/conf/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /docker/es/data:/usr/share/elasticsearch/data -v /docker/es/plugins:/usr/share/elasticsearch/plugins -v /docker/es/logs:/usr/share/elasticsearch/logs --privileged=true elasticsearch:7.12.1
    
  6. 異常處理

    好事多磨孤钦,一般這里都會出點小問題歧斟,啟動失敗使用 docker logs es | grep error 命令來查看報錯信息纯丸。我遇到的有異常:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    解決方案:

    1. 修改配置sysctl.conf:
    vi /etc/sysctl.conf
    2. 在尾行添加以下內(nèi)容:
    vm.max_map_count=655300
    3. 刷新配置:
    sysctl -p
    
  7. 測試,在瀏覽器中訪問服務(wù)地址+9200的端口静袖,可以顯示以下信息證明安裝成功

    PS:如果打不開觉鼻,請檢查es是否正確啟動以及9200端口是否開放

    {
      "name" : "node-1",
      "cluster_name" : "my-application",
      "cluster_uuid" : "b-ovHR-GRvunpTmWOfoLKw",
      "version" : {
        "number" : "7.12.1",
        "build_flavor" : "default",
        "build_type" : "docker",
        "build_hash" : "3186837139b9c6b6d23c3200870651f10d3343b7",
        "build_date" : "2021-04-20T20:56:39.040728659Z",
        "build_snapshot" : false,
        "lucene_version" : "8.8.0",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
    

安裝es的可視化面板 kibana

  1. 拉取鏡像

    docker pull kibana:7.12.1
    
  2. 在宿主機(jī)創(chuàng)建和容器內(nèi)共享的目錄

    mkdir -p /docker/kibana/conf
    
  3. 創(chuàng)建配置文件
    vi /docker/kibana/conf/kibana.yml

    server.name: kibana
    server.host: "0.0.0.0"
    elasticsearch.hosts: ["http://你的es地址:9200"]   
    xpack.monitoring.ui.container.elasticsearch.enabled: true
    
  4. 構(gòu)建容器

    docker run -p 5601:5601 -d --name kibana -v /docker/kibana/conf/kibana.yml:/usr/share/kibana/config/kibana.yml --privileged=true kibana:7.12.1
    
  5. 訪問測試:http://服務(wù)ip:5601

安裝es的ik分詞器

  1. 下載安裝包

    wget https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.12.1
    
  2. 解壓安裝包

    PS:這個安裝包解壓完文件是分散的,所以需要在 plugins 目錄下先建好放置文件的目錄

    mkdir /docker/es/plugins/ik
    mv elasticsearch-analysis-ik-7.12.1.zip /docker/es/plugins/ik/
    cd /docker/es/plugins/ik
    unzip elasticsearch-analysis-ik-7.12.1.zip
    rm -rf elasticsearch-analysis-ik-7.12.1.zip
    
  3. 重啟es容器

    docker restart es
    
  4. 注意事項

    安裝es的ik分詞器可能會導(dǎo)致es內(nèi)存溢出队橙,可以在es配置中增加內(nèi)存限制

    indices.fielddata.cache.size: 50%
    

es在laravel中的應(yīng)用

  1. 安裝composer組件包

    composer require elasticsearch/elasticsearch "7.12.x" --ignore-platform-reqs
    
  2. 配置

    # 在 .env 文件中加入es的地址配置坠陈,如果是集群存在多個地址則用 ,隔開
    ES_HOSTS=172.17.0.8,172.17.0.9,172.17.0.10
    # 在 config/database.php 配置文件中加入
    # 端口不用加捐康,默認(rèn)就是9200仇矾,但是如果改了端口那這里就要加入端口的配置
    'elasticsearch' => [
     'hosts' => explode(',', env('ES_HOSTS')),
    ]
    
  3. 初始化 Elasticsearch 對象,并注入到 laravel 容器中

    在 App/Providers/AppServiceProvider.php 文件的register方法中定義服務(wù)對象

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Elasticsearch\ClientBuilder as ESClientBuilder;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Register any application services.
         *
         * @return void
         */
        public function register()
        {
            // 注冊一個名為 es 的單例
            $this->app->singleton('es', function () {
                // 從配置文件讀取 Elasticsearch 服務(wù)器列表
                $builder =  ESClientBuilder::create()->setHosts(config('database.elasticsearch.hosts'));
                // 如果是開發(fā)環(huán)境
                if (app()->environment() === 'local'){
                    // 配置日志吹由,Elasticsearch 的請求和返回數(shù)據(jù)將打印到日志文件中若未,便于調(diào)試
                    $builder->setLogger(app('log')->driver());
                }
                
                return $builder->build();
            });
        }
    
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            //
        }
    }
    

    然后就可以在項目中使用 app('es') 的方式來調(diào)用es了

  4. 測試是否配置成功

    [root@localhost blog]# php artisan tinker
    Psy Shell v0.10.8 (PHP 7.4.20 — cli) by Justin Hileman
    >>> app('es')->info()
    => [
         "name" => "node-1",
         "cluster_name" => "my-application",
         "cluster_uuid" => "b-ovHR-GRvunpTmWOfoLKw",
         "version" => [
           "number" => "7.12.1",
           "build_flavor" => "default",
           "build_type" => "docker",
           "build_hash" => "3186837139b9c6b6d23c3200870651f10d3343b7",
           "build_date" => "2021-04-20T20:56:39.040728659Z",
           "build_snapshot" => false,
           "lucene_version" => "8.8.0",
           "minimum_wire_compatibility_version" => "6.8.0",
           "minimum_index_compatibility_version" => "6.0.0-beta1",
         ],
         "tagline" => "You Know, for Search",
       ]
    >>>
    

    使用 app('es')->info() 可以打印出es相關(guān)信息,則安裝配置成功

  5. 在laravel中簡單封裝一個類來使用es

    這里只以搜索為例倾鲫,增刪改都很簡單粗合,就不演示了

    創(chuàng)建一個 service 類,來處理es搜索的結(jié)構(gòu)體

    <?php
    /**
     * Created by PhpStorm
     * User: Ricky Wong
     * Date: 2021/8/1
     * Time: 19:58
     */
    
    namespace App\Services;
    
    
    class ElasticSearchService
    {
        /**
         * 定義基礎(chǔ)結(jié)構(gòu)體
         * @var array
         */
        protected $params = [
            'index' => 'products',
            'type' => '_doc',
            'body' => [
                'query' => [
                    'bool' => [
                        'filter' => [],
                        'must'  => []
                    ]
                ]
            ]
        ];
    
        /**
         * 分頁
         * @param int $size 每頁顯示多少條
         * @param int $page 頁碼
         * @return $this
         */
        public function paginate($size = 20, $page = 1)
        {
            $this->params['body']['from'] = ($page - 1) * $size;
            $this->params['body']['size'] = $size;
    
            return $this;
        }
    
        /**
         * 數(shù)據(jù)狀態(tài)值精確查詢
         * @param int $status 狀態(tài)標(biāo)識
         * @return $this
         */
        public function status($status = 1)
        {
            $this->params['body']['query']['bool']['filter'] = [
                'term' => ['status' => $status]
            ];
    
            return $this;
        }
    
        /**
         * 排序
         * 如需多字段排序多次調(diào)用此方法即可
         * @param string $field 排序字段
         * @param string $direction 排序方式 asc|desc
         * @return $this
         */
        public function order($field, $direction)
        {
            if (!isset($this->params['body']['sort'])) {
                $this->params['body']['sort'] = [];
            }
            $this->params['body']['sort'][] = [$field => $direction];
    
            return $this;
        }
    
        /**
         * 關(guān)鍵詞乌昔,按多字段權(quán)重搜索
         * @param array $keywords 搜索詞數(shù)組
         * @return $this
         */
        public function keywords($keywords)
        {
            $keywords = is_array($keywords) ? $keywords : [$keywords];
            foreach ($keywords as $keyword) {
                $this->params['body']['query']['bool']['must'][] = [
                    'multi_match' => [
                        'query' => $keyword,
                        'fields' => [
                            'long_name^3',
                            'name^2'
                        ],
                        // most_fields 多字段匹配度更高   best_fields  完全匹配占比更高
                        'type' => 'most_fields'
                    ]
                ];
            }
    
            return $this;
        }
    
        /**
         * 指定需要返回的字段
         * @param array $fields 字段數(shù)組
         * @return $this
         */
        public function select($fields = [])
        {
            $this->params['body']['_source'] = $fields;
    
            return $this;
        }
    
        /**
         * 搜索詞高亮設(shè)置
         * @param array $fields 高亮搜索詞數(shù)組
         * @return $this
         */
        public function highlight($fields)
        {
            $array = [];
            foreach ($fields as $field) {
                $array[$field] = (object)[];
            }
    
            $this->params['body']['highlight'] = [
                // 自定義高亮樣式
                'pre_tags' => "<p style='color: red;'>",
                'post_tags' => "</p>",
                'fields' => $array
            ];
    
            return $this;
        }
    
        /**
         * 返回結(jié)構(gòu)體
         * @return array
         */
        public function getParams()
        {
            return $this->params;
        }
    }
    

    創(chuàng)建控制器隙疚,在其中定義方法來調(diào)用service,這里只展示這個方法

        /**
         * 搜索
         * @param Request $request
         * @param ElasticSearchService $service
         * @return \Illuminate\Http\JsonResponse
         */
        public function search(Request $request, ElasticSearchService $service)
        {
            $page = $request->input('page', 1);
            $size = $request->input('perPage', 20);
            $keyword =  $request->input('keyword', '');
            $order = $request->input('order', '');
            try {
                $builder = $service->status()->paginate($size, $page);
                if (!empty($keyword)) {
                    // 將多個以空格隔開的關(guān)鍵詞轉(zhuǎn)為數(shù)組
                    $keywords = array_filter(explode(' ', $keyword));
                    $builder->keywords($keywords);
                }
                if (!empty($order)) {
                    if (preg_match('/^(.+)_(asc|desc)$/', $order,$match)) {
                        $builder->order($match[1], $match[2]);
                    }
                }
                $params = $builder->select(['name', 'long_name'])->highlight(['name', 'long_name'])->getParams();
    
                return response()->json(['result' => true, 'data' => app('es')->search($params)]);
            } catch (\Exception $e) {
                Log::error($e->getMessage());
                return response()->json(['result' => false, 'data' => []]);
            }
        }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磕道,一起剝皮案震驚了整個濱河市供屉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溺蕉,老刑警劉巖伶丐,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疯特,居然都是意外死亡哗魂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門漓雅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來录别,“玉大人,你說我怎么就攤上這事邻吞∽樘猓” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵抱冷,是天一觀的道長崔列。 經(jīng)常有香客問我,道長旺遮,這世上最難降的妖魔是什么峻呕? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任利职,我火速辦了婚禮,結(jié)果婚禮上瘦癌,老公的妹妹穿的比我還像新娘猪贪。我一直安慰自己,他們只是感情好讯私,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布热押。 她就那樣靜靜地躺著,像睡著了一般斤寇。 火紅的嫁衣襯著肌膚如雪桶癣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天娘锁,我揣著相機(jī)與錄音牙寞,去河邊找鬼。 笑死莫秆,一個胖子當(dāng)著我的面吹牛间雀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镊屎,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼惹挟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缝驳?” 一聲冷哼從身側(cè)響起连锯,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎用狱,沒想到半個月后运怖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夏伊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年驳规,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片署海。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖医男,靈堂內(nèi)的尸體忽然破棺而出砸狞,到底是詐尸還是另有隱情,我是刑警寧澤镀梭,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布刀森,位于F島的核電站,受9級特大地震影響报账,放射性物質(zhì)發(fā)生泄漏研底。R本人自食惡果不足惜埠偿,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榜晦。 院中可真熱鬧冠蒋,春花似錦、人聲如沸乾胶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽识窿。三九已至斩郎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喻频,已是汗流浹背缩宜。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留甥温,地道東北人锻煌。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像窿侈,于是被迫代替她去往敵國和親炼幔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容