Laravel 教程:如何在有限的服务器资源中集成 Elasticsearch 搜索引擎
如何以最少的资源消耗将 Elasticsearch 添加到 Laravel 应用服务器上的
最近,我已经将cro-tool.com 上的搜索功能从数据库驱动的搜索引擎更换到 Elasticsearch
。 这不是一个容易的过程,有几个障碍需要克服,但是最终的结果值得我所有努力。
让我们从头开始。 在更换之前,我必须指定我要搜索的字段,如何在搜索页面上对这些结果进行排序以及如何匹配这些字段(比如 LIKE %%等)。这意味着要进行大量手动工作才能正确显示搜索结果。 使用联表查询和where子句查找记录,如果没有结果与 SQL 查询匹配,该怎么办? 好吧,没有结果。 SQL 数据库并不了解记录的相关性,因此需要人工完成一些搜索引擎中已经内置的工作。
Elasticsearch
我想解决的是上一段中我突出显示的最后一个问题,即显示一些有关联性的搜索结果,因为我宁愿显示较少的相关搜索结果,也不显示根本没有关系的搜索结果。 搜索引擎非常适合执行类操作。 为了找到不错的搜索引擎,我审视了一下我自己的经验。使用的比较多的 Apache Solr
,并且我非常喜欢使用它。 但我也知道这可能会占用大量资源。 所以我改为使用 Elasticsearch
。 我知道服务器资源非常有限,因此使用搜索引擎已经是一场赌博。 我以为 Elasticsearch
的资源使用率较低,但是这种想法是凭空产生的,实际上我没有验证过这是否正确。
我知道 Laravel 有一个称为 laravel/scout
的官方软件包,该软件包有一些配置项,可以让您使用 Elasticsearch
作为搜索引擎而不是 Algolia
。 这是我使用 Elasticsearch
的另一个原因,因为它可以快速将其集成到现有的Laravel
应用程序中,而无需重写许多现有逻辑。
集成 Elasticsearch 到 Laravel 应用
我需要使用 Elasticsearch
和 laravel/scout
,因此我搜索到一个 composer
程序包将这两个连接起来 matchish/laravel-scout-elasticsearch
。 它似乎功能非常齐全,甚至可以让您自定义请求,然后再发送给搜索引擎,完美无缺!
安装软件包并发布配置文件后,我开始编写能够将文档索引到 Elasticsearch
中所需的代码。
配置 Elasticsearch
如果您了解我的话,就会知道我是 Docker
和 docker-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。
迁移的效果很好,因为你可以在服务器硬件的基础上使用一个功能完善的搜索引擎,之前这台服务器可能会被认为是性能上是不够的。
当然,这也不是一个长久之计,因为一旦你的网站流量加大,变得繁忙,服务器资源就得升级。
不过这个解决方案能把这个过程再拉长一些,强行续命,这可不是一件坏事。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。