8

Laravel 教程:如何在有限的服务器资源中集成 Elasticsearch 搜索引擎

 3 years ago
source link: https://zhuanlan.zhihu.com/p/130673144
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.

Laravel 教程:如何在有限的服务器资源中集成 Elasticsearch 搜索引擎

摈弃世俗浮躁,追求技术精湛

原文链接:https://learnku.com/laravel/t/42995
讨论请前往专业的 Laravel 开发者论坛:https://learnku.com/Laravel

如何以最少的资源消耗将 Elasticsearch 添加到 Laravel 应用服务器上的

最近,我已经将cro-tool.com 上的搜索功能从数据库驱动的搜索引擎更换到 Elasticsearch。 这不是一个容易的过程,有几个障碍需要克服,但是最终的结果值得我所有努力。

让我们从头开始。 在更换之前,我必须指定我要搜索的字段,如何在搜索页面上对这些结果进行排序以及如何匹配这些字段(比如 LIKE %%等)。这意味着要进行大量手动工作才能正确显示搜索结果。 使用联表查询和where子句查找记录,如果没有结果与 SQL 查询匹配,该怎么办? 好吧,没有结果。 SQL 数据库并不了解记录的相关性,因此需要人工完成一些搜索引擎中已经内置的工作。

Elasticsearch

我想解决的是上一段中我突出显示的最后一个问题,即显示一些有关联性的搜索结果,因为我宁愿显示较少的相关搜索结果,也不显示根本没有关系的搜索结果。 搜索引擎非常适合执行类操作。 为了找到不错的搜索引擎,我审视了一下我自己的经验。使用的比较多的 Apache Solr,并且我非常喜欢使用它。 但我也知道这可能会占用大量资源。 所以我改为使用 Elasticsearch。 我知道服务器资源非常有限,因此使用搜索引擎已经是一场赌博。 我以为 Elasticsearch 的资源使用率较低,但是这种想法是凭空产生的,实际上我没有验证过这是否正确。

我知道 Laravel 有一个称为 laravel/scout 的官方软件包,该软件包有一些配置项,可以让您使用 Elasticsearch 作为搜索引擎而不是 Algolia。 这是我使用 Elasticsearch 的另一个原因,因为它可以快速将其集成到现有的Laravel 应用程序中,而无需重写许多现有逻辑。

集成 Elasticsearch 到 Laravel 应用

我需要使用 Elasticsearchlaravel/scout,因此我搜索到一个 composer 程序包将这两个连接起来 matchish/laravel-scout-elasticsearch。 它似乎功能非常齐全,甚至可以让您自定义请求,然后再发送给搜索引擎,完美无缺!

安装软件包并发布配置文件后,我开始编写能够将文档索引到 Elasticsearch 中所需的代码。

配置 Elasticsearch

如果您了解我的话,就会知道我是 Dockerdocker-compose 的忠实拥护者。 所以自然地,我设置了 docker-compose.yml 文件来为我启动一个Elasticsearch 服务器,这是我使用的配置:

version: "2.3"
services:
  elasticsearch:
    image: elasticsearch:7.6.1
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
    ports:
      - "127.0.0.1:9200:9200"
    volumes:
      - ./storage/elasticsearch:/usr/share/elasticsearch/data

如您所见,我设置了 Java 运行搜索引擎内存占用 256mb 。 这是一个很小的数目,数据集不是很大,毕竟我的服务器资源有限。 docker-compose 文件还告诉 Elasticsearch 容器仅在本地主机上开放 9200 端口。 我不想将此服务开放到外面,只有在同一台计算机上的应用程序才能直接访问它。 如您所见,我挂载了一个目录,因此 Elasticsearch 中的所有数据都将被写入Laravel 应用程序中的 storage/elasticsearch 文件夹中。 这个文件夹显然包含一个 .gitignore 文件,因为我不想将这些数据纳入 Git 存储库中。

部署新的搜索引擎

当搜索功能从数据库查询转换为对 Elasticsearch 的 API 请求时,就该部署所有内容了。 一切顺利... , 直到我尝试运行 Elasticsearch docker 容器。 服务器没有足够的 RAM 来运行 Java Runtime ,并且容器拒绝启动。 是时候开始我的骚操作了。

解决内存问题

我有两个选择:升级服务器或把 Apache 更换为 Nginx。 我之所以选择后者,是因为以下原因:即使没有人访问网站,Apache 也会使用更多的RAM。 它启动了 worker 并且使其保持启用状态,直到有新的访问使用为止。 另一方面,Nginx 能够根据需要启动 worker 。 这意味着,如果网站上没有任何人访问,那么它就不会开启新的 worker,这意味着它在空闲时运行占用的资源要少得多。当有更多访问时,Apache 会继续为新的访问生成 worker ,并且随着时间的推移,worker 会不断增加。 Nginx 可以更有效地利用 worker ,并能够以更少的资源提供服务。 这就是为什么我认为切换到 Nginx 可能会给我足够的免费资源来启动 Elasticsearch 的原因。

迁移完成之后,我确实能够启动 Elasticsearch,因为 Nginx 的 RAM 使用率比 Apache 低几倍。 即使访问数量增多时,RAM 的使用仍处于可控范围。 另一部分原因是因为我指定了 Java Runtime 允许用于 Elasticsearch 的最大内存量。

在资源较少的服务器上运行Elasticsearch并不是一件轻松的事情。对于这种特殊情况,我必须将项目从Apache迁移到Nginx,以便顺利使用Docker和启动Elasticsearch。 迁移的效果很好,因为你可以在服务器硬件的基础上使用一个功能完善的搜索引擎,之前这台服务器可能会被认为是性能上是不够的。 当然,这也不是一个长久之计,因为一旦你的网站流量加大,变得繁忙,服务器资源就得升级。 不过这个解决方案能把这个过程再拉长一些,强行续命,这可不是一件坏事。

原文链接:https://learnku.com/laravel/t/42995
讨论请前往专业的 Laravel 开发者论坛:https://learnku.com/Laravel


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK