热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL与ElasticSearch同步

碰到个全文搜索的需求,鉴于上家公司的业务日志查询用的就是ELK,效果还不错,所以用ElasticSearch做搜索引擎感觉问题不大。由于是针对业务数据做全文搜索,数据存在数据库里,

碰到个全文搜索的需求,鉴于上家公司的业务日志查询用的就是 ELK ,效果还不错,所以用 ElasticSearch 做搜索引擎感觉问题不大。由于是针对业务数据做全文搜索,数据存在数据库里,所以将这些数据同步到 ES ,怎么做呢,无非两种方式:一是通过 ES 的 API 进行增删改查,二是通过中间件进行数据全量、增量的同步。很明显 API 的方式比较麻烦,那就试试第二种吧。中间件的方式总共搜了三种方案:

  1. elasticsearch-jdbc
    一个 独立的第三方工具。使用很简单,写个 shell 脚本就行了:

    《PostgreSQL 与 ElasticSearch 同步》 shell 脚本例子
    这个工具的活跃度也很高,前一天还有人提 issue 。问题是它的版本兼容性:
    《PostgreSQL 与 ElasticSearch 同步》 目前最高只兼容Elasticsearch2.3.4
    elastic 官方已经把 Elasticsearch、Logstash 、Kibana 版本升级到5.x版本,现在统一是5.2.2,这和以前的2.x在插件机制上有一些差异,个人倾向于使用最新版,所以这个工具暂时放弃了。

  2. logstash-input-jdbc
    logstash 的一个jdbc 插件,ruby 写的,据说不太好装,logstash 印象里一直是做日志文件收集的,尤其我们的数据库不是常见的 mysql、oracle,而是 postgresql ,感觉趟这个坑的人不多,没信心一定能成功。

  3. PostgreSQL 的 ElasticSearch 同步插件
    直接用 PostgreSQL 的插件,国内 PG 的大牛德哥在云栖社区贴了篇文章《PostgreSQL内核扩展之 – ElasticSearch同步插件》,写的很详细,显然这个方案跑通过了,所以就选了这个方案。

因为这个方案涉及了很多安装步骤,中间出现了很多坑,所以单独写篇文章记录一下,能让后来者少走些弯路吧。

安装前准备

Mac 平台
数据库:PostgreSQL 9.5.4
数据库客户端:pgAdmin 4
Python 2.7.10

安装并运行 ElasticSearch

官网下载 ElasticSearch ,解压缩,以下命令运行:

bin/elasticsearch
安装 PostgreSQL 插件 multicorn

github下载 Multicorn:

git clone https://github.com/Kozea/Multicorn /tmp/multicorn
cd $_

由于 Multicorn 的 master 代码在 OS X 环境有问题,有几个步骤要手工执行:
1.修改文件 Makefile 的93行,将 darwin 的首字母改成大写:Darwin
2.执行 make
3.sudo ARCHFLAGS=”-arch x86_64″ make install
具体原因看这个issue里的解释
4.执行 make install

pg 数据库中新建一个 EXTENSION

psql -h {ip} -p {port} -d {database} -U {username}
-- 新建名为 multicorn 的 EXTENSION
create extension multicorn ;
安装 PostgreSQL 插件 pg-es-fdw

github 下载 pg-es-fdw:

git clone https://github.com/Mikulas/pg-es-fdw /tmp/pg-es-fdw
cd $_
sudo python setup.py install
基于 multicorn 创建 foreign server

CREATE SERVER multicorn_es FOREIGN DATA WRAPPER multicorn
OPTIONS (
wrapper 'dite.ElasticsearchFDW'
);

PostgreSQL 的建 server 的语法不再赘述。wrapper 的值 dite.ElasticsearchFDW 的定义就在 pg-es-fdw 插件的 dite 目录 __init__.py 文件里,有兴趣的可以看看。

创建测试表

CREATE TABLE articles (
id serial PRIMARY KEY,
title text NOT NULL,
content text NOT NULL,
created_at timestamp
);
创建外部表

CREATE FOREIGN TABLE articles_es (
id bigint,
title text,
content text
) SERVER multicorn_es OPTIONS (host '127.0.0.1', port '9200', node 'test', index 'articles');

参数 host 和 port 是 elasticsearch 服务的主机和端口号,参数 node 表示对应的 ES 中的索引名是 test ,参数 index 表示对应的 ES 中的类型名是 articles 。所以对应的 ES 中该表下的数据 url 访问路径是:
http://localhost:9200/test/articles/{id}

创建触发器

对实体表,创建触发器函数,在用户对实体表插入,删除,更新时,通过触发器函数自动将数据同步到对应ES的外部表。同步过程调用 FDW 的接口,对 ES 进行索引的建立,更新,删除:

CREATE OR REPLACE FUNCTION index_article() RETURNS trigger AS $def$
BEGIN
INSERT INTO articles_es (id, title, content) VALUES
(NEW.id, NEW.title, NEW.content);
RETURN NEW;
END;
$def$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION reindex_article() RETURNS trigger AS $def$
BEGIN
UPDATE articles_es SET
title = NEW.title,
cOntent= NEW.content
WHERE id = NEW.id;
RETURN NEW;
END;
$def$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION delete_article() RETURNS trigger AS $def$
BEGIN
DELETE FROM articles_es a WHERE a.id = OLD.id;
RETURN OLD;
END;
$def$ LANGUAGE plpgsql;
CREATE TRIGGER es_insert_article
AFTER INSERT ON articles
FOR EACH ROW EXECUTE PROCEDURE index_article();
CREATE TRIGGER es_update_article
AFTER UPDATE OF title, content ON articles
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE reindex_article();
CREATE TRIGGER es_delete_article
BEFORE DELETE ON articles
FOR EACH ROW EXECUTE PROCEDURE delete_article();
测试验证

插入一条表记录:

insert into articles(title, content) values ('测试内容1', '测试标题1');

查询 ES ,检查数据是否已同步:

curl 'localhost:9200/test/articles/_search?q=*:*&pretty'

结果如下:

《PostgreSQL 与 ElasticSearch 同步》 验证同步 ES 的结果

提醒

之前部署这个还踩了个坑,发现 PG 数据库的数据在 ES 中一直没有,原来因为我给elasticsearch安装了x-pack插件,导致给es添加了默认的安全机制,而pg-es-fdw插件中却没有传递访问es的用户名密码,所以一直不通。


推荐阅读
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • Hadoop平台警告解决:无法加载本机Hadoop库的全面应对方案
    本文探讨了在Hadoop平台上遇到“无法加载本机Hadoop库”警告的多种解决方案。首先,通过修改日志配置文件来忽略该警告,这一方法被证明是有效的。其次,尝试指定本地库的路径,但未能解决问题。接着,尝试不使用Hadoop本地库,同样没有效果。然后,通过替换现有的Hadoop本地库,成功解决了问题。最后,根据Hadoop的源代码自行编译本地库,也达到了预期的效果。以上方法适用于macOS系统。 ... [详细]
  • 在Ubuntu系统中配置Python环境变量是确保项目顺利运行的关键步骤。本文介绍了如何将Windows上的Django项目迁移到Ubuntu,并解决因虚拟环境导致的模块缺失问题。通过详细的操作指南,帮助读者正确配置虚拟环境,确保所有第三方库都能被正确识别和使用。此外,还提供了一些实用的技巧,如如何检查环境变量配置是否正确,以及如何在多个虚拟环境之间切换。 ... [详细]
  • 通过将常用的外部命令集成到VSCode中,可以提高开发效率。本文介绍如何在VSCode中配置和使用自定义的外部命令,从而简化命令执行过程。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
  • 本文详细介绍了在 Ubuntu 系统上搭建 Hadoop 集群时遇到的 SSH 密钥认证问题及其解决方案。通过本文,读者可以了解如何在多台虚拟机之间实现无密码 SSH 登录,从而顺利启动 Hadoop 集群。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 使用 SourceTree 管理 SVN 代码仓库的详细指南
    SourceTree 是一款功能强大的 Git 管理工具,但很多人不知道它同样支持管理 SVN 代码仓库。本文将详细介绍如何使用 SourceTree 来管理和操作 SVN 代码仓库。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • 优秀到卓越就差比他更快搭建elk集群架构上篇
    工作原理开源分布式搜索引擎,特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制 ... [详细]
  • 1.ELK系统是什么ELK是一套日志中心解决方案,其三个字母分别表示:Elasticsearch:负责日志存储及检索Logstash&#x ... [详细]
author-avatar
真理往往是废话
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有