3、PostgreSQL深度解析:PostgreSQL特性、在ThingsBoard中的角色、安装与配置、主从复制方案
好,咱们进入第三讲。这一章我打算把PostgreSQL彻底聊透。为什么?因为它是ThingsBoard的默认数据库,也是生产环境中最靠谱的选择。我见过太多团队在数据库选型上翻车,最后灰溜溜地换回PostgreSQL。说白了,选它不一定最潮,但一定最稳。
3.1 PostgreSQL核心特性:为什么ThingsBoard选它?
先说说PostgreSQL的几个硬核特性。我个人习惯把它叫做“数据库界的瑞士军刀”——功能太全了。
- ACID事务:完全支持,而且实现得很扎实。我在项目中遇到过并发写入导致数据错乱的情况,换成PostgreSQL后问题迎刃而解。
- 扩展性:支持自定义数据类型、函数、索引类型。ThingsBoard就用到了它的JSONB类型来存储设备属性。
- MVCC(多版本并发控制):读不阻塞写,写不阻塞读。这对IoT场景太重要了——你想想看,设备数据一直在写,用户同时要查报表,如果读写互相锁死,系统就崩了。
- 强大的索引:B-tree、Hash、GiST、GIN、BRIN……特别是BRIN索引,对时序数据非常友好。
- 流复制:原生支持主从复制,配置简单,延迟低。
核心观点:PostgreSQL在ThingsBoard中扮演的是“持久化基石”的角色。所有设备元数据、用户信息、规则链定义、告警记录都存这里。时序数据虽然可以交给Cassandra或TimescaleDB,但元数据这块,PostgreSQL是雷打不动的。
3.2 PostgreSQL在ThingsBoard中的具体角色
ThingsBoard的架构里,PostgreSQL主要负责三块内容:
- 实体数据:设备、资产、租户、用户、仪表板、规则链等。这些数据量不大,但关系复杂,用关系型数据库管理最合适。
- 最新遥测数据:每个设备的最新属性值、最新遥测值。ThingsBoard用了一张专门的表来存“最新值”,方便快速查询。
- 告警与事件:告警记录、审计日志、事件数据。这些需要支持复杂查询和关联。
嗯,这里要注意:时序数据(历史遥测)默认也可以存PostgreSQL,但生产环境我建议别这么干。数据量一上来,查询性能会急剧下降。我踩过这个坑——当时一个项目每天产生500万条遥测数据,PostgreSQL撑了三天就扛不住了。后来切到TimescaleDB才解决。
3.3 安装与配置:从零开始搭一个稳当的环境
安装PostgreSQL其实不难,但配置才是关键。我直接上干货。
3.3.1 安装
以Ubuntu 20.04为例:
# 安装
sudo apt update
sudo apt install postgresql postgresql-contrib
# 检查状态
sudo systemctl status postgresql
# 进入命令行
sudo -u postgres psql
安装完成后,记得设置密码:
ALTER USER postgres WITH PASSWORD 'your_strong_password';
3.3.2 配置优化
配置文件在 /etc/postgresql/14/main/postgresql.conf。我一般会改这几个参数:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| shared_buffers | 内存的25% | PostgreSQL自己的缓存,别设太大,要给OS留空间 |
| effective_cache_size | 内存的50%-75% | 告诉优化器OS能缓存多少数据 |
| work_mem | 4-8MB | 排序和哈希操作的内存,设太大容易OOM |
| maintenance_work_mem | 64-256MB | VACUUM、CREATE INDEX等维护操作 |
| wal_buffers | 16-64MB | WAL日志缓冲区,写入频繁时调大 |
| max_connections | 100-200 | ThingsBoard默认连接池不大,够用就行 |
我的经验:对于ThingsBoard,shared_buffers设到内存的20%就差不多了。我曾经给一台32G内存的服务器设了12G,结果系统频繁swap,性能反而下降。记住,PostgreSQL依赖OS的文件系统缓存,别把内存全占了。
3.3.3 创建ThingsBoard数据库
CREATE DATABASE thingsboard;
CREATE USER tb_user WITH PASSWORD 'tb_password';
GRANT ALL PRIVILEGES ON DATABASE thingsboard TO tb_user;
-- 别忘了给public schema授权
\c thingsboard
GRANT ALL ON SCHEMA public TO tb_user;
3.4 主从复制方案:高可用的基石
单机PostgreSQL扛不住生产环境。一旦挂了,整个ThingsBoard就瘫了。所以主从复制是必须的。
3.4.1 流复制原理
PostgreSQL的流复制,说白了就是主库把WAL日志实时传给从库,从库重放这些日志。延迟通常在毫秒级。
我习惯用异步复制,性能好,丢数据的概率极低。如果对数据一致性要求极高,可以用同步复制,但性能会下降30%左右。
3.4.2 配置步骤
主库配置:
# postgresql.conf
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1024 # 保留1GB的WAL日志,防止从库追不上
# pg_hba.conf 添加从库IP
host replication repl_user 192.168.1.0/24 md5
创建复制用户:
CREATE USER repl_user WITH REPLICATION PASSWORD 'repl_password';
从库配置:
# 先停掉从库的PostgreSQL
sudo systemctl stop postgresql
# 清空从库数据目录
rm -rf /var/lib/postgresql/14/main/*
# 从主库拉取基础备份
pg_basebackup -h 主库IP -U repl_user -D /var/lib/postgresql/14/main/ -P -R
# 启动从库
sudo systemctl start postgresql
这里的 -R 参数会自动生成 standby.signal 文件,告诉PostgreSQL这是从库。
3.4.3 验证复制状态
在主库执行:
SELECT * FROM pg_stat_replication;
如果看到一行记录,说明复制正常。重点关注 write_lag 和 flush_lag 字段,正常情况下应该在毫秒级。
避坑指南:我曾经遇到一个坑——从库复制延迟越来越大,最后差了十几分钟。查了半天发现是主库的 wal_keep_size 设得太小,从库断连后WAL日志被清理了。解决办法是调大 wal_keep_size,或者启用复制槽(pg_create_physical_replication_slot)。
3.4.4 故障切换
主库挂了怎么办?手动提升从库为主库:
# 在从库执行
pg_ctl promote -D /var/lib/postgresql/14/main/
然后修改ThingsBoard的配置文件,把数据库连接指向新的主库。如果用了HAProxy或Pgpool-II,可以自动切换,但那是进阶话题了。
3.5 小结
PostgreSQL在ThingsBoard里,就像地基之于房子。地基不稳,上层建筑再花哨也没用。我个人建议:
- 开发环境用单机PostgreSQL就够了
- 测试环境至少配一主一从
- 生产环境建议一主两从,再加一个Pgpool-II做负载均衡
下一章咱们聊TimescaleDB——专门为时序数据设计的数据库,和PostgreSQL配合起来,堪称ThingsBoard的黄金搭档。