精華 [程序新闻] FlintHub 程序介绍

👑Lv.11 元老 🌏 正式会员
2026-08-27 12:22:30

轻量级 PHP 社区系统(论坛 + 博客),基于自研 SplitDB 纯 SQLite 分片引擎。

版本:V1.0.0 | 兼容 PHP 8.0.2(SQLite 3.33.0)|

编码:UTF-8 without BOM + LF,用于快速了解本程序的全貌与优势。


一、项目概述

FlintHub(原名 SoSite)是一套轻量级 PHP 社区系统,提供论坛(帖子/回复/版块)、博客、用户中心、后台管理、插件系统等完整能力。它最核心的特点是:彻底剥离 MySQL,全部数据由纯 SQLite 分片引擎(SplitDB)承载,从"单库单表"升级为"分片 + 索引 + 缓存"的架构,在保留 PHP 极简部署优势的同时,解决了大数据量下的性能问题。

项 说明
项目定位 轻量级 PHP 社区系统(论坛 + 博客一体)
当前版本 FlintHub V1.0.0(由 SoSite 5.0 MySQL 版重构而来)
运行环境 PHP 8.0.2(SQLite 3.33.0),Nginx / Apache / phpstudy 均可
数据引擎 SplitDB —— 纯 SQLite 分片引擎(无任何 MySQL 依赖)
数据规模实测 5 万用户、19.2 万帖、16 万回复、235 万搜索索引行
目录约定 站点根目录为可运行骨架;update/ 为同步镜像 + 全部文档

演进脉络:SoSite 5.0(MySQL 单库)→ 重构为 SoSite 1.0(SplitDB 纯 SQLite 分片引擎)→ 品牌重命名 FlintHub。


二、核心架构:SplitDB 纯 SQLite 分片引擎

2.1 数据分层

data/
├── meta/                        # 元数据层(SQLite 库)
│   ├── business.sqlite          # 非分片业务:用户/版块/设置/博客/私信/附件/标签/投票
│   ├── main_index.sqlite        # 帖子主索引 topic_index(19.2万行) + 回复定位索引 reply_index(16万行)
│   ├── search/                  # 搜索索引季度分文件 search_{YYYYQn}.sqlite(4 文件,235 万行)
│   ├── global_id.sqlite         # 全局 ID 生成器(topic/reply 原子取号游标)
│   ├── sessions.sqlite          # 会话存储(SQLite handler)
│   └── task_queue/queue_{0..2}.sqlite  # 异步任务队列(三队列打散锁竞争)
├── bucket/active/{季度}/{0..31}.sqlite  # 帖子/回复真相源(季度时序 + ID2 哈希分桶)
├── bucket/archive/              # 18 个月以上冷数据归档桶
└── extern/{年}/{季}/{桶}/        # 正文外置:存量 .bin/.idx 偏移索引,新帖 .txt(读取自动回退)

2.2 分片与路由规则(ShardRouter)

  • 一级分区:季度时序分区(YYYYQn,如 2026Q3),新数据写入当前季度;
  • 二级分区:哈希分桶(默认 32 桶),写入路由 = ID % 桶数量;
  • 读取永远以 main_index.bucket_path 为准,不再二次哈希;未来季度可平滑升级 32 → 64 → 128 桶,历史数据零迁移。

2.3 写入与读取链路

写入 = global_id 原子取号 → 季度分区 + ID2 哈希 → extern 正文原子写(tmp+rename)
     → 桶 topic/reply 真相源 → main_index 索引行(最终一致性,队列可选)
读取 = 列表/分页走 main_index(索引行含 bucket_path)→ 详情读桶 + extern(.bin/.idx 优先,缺失回退 .txt)
搜索 = 自研 bigram 倒排索引(季度分文件,SearchIndexStore)

2.4 引擎关键组件(app/SplitDB/)

组件 职责 亮点
DBFactory SQLite 连接池 单进程 LRU 最大 8 句柄,统一 6 条 PRAGMA(WAL/busy_timeout),禁持久连接
IDGenerator 全局 ID 生成 BEGIN IMMEDIATE 写锁事务原子取号(兼容无 RETURNING 的 SQLite 3.33)
ShardRouter 分片路由 季度 + 哈希双级分区,路径推导唯一依据
ExternStorage 正文外置存储 tmp+rename 原子写;存量 .bin/.idx 偏移索引(fseek 定位,懒加载);编辑后作废 .idx 条目回退 .txt(修复虚拟主机编辑不生效)
Queue / QueueConsumer 异步任务队列 三队列打散锁竞争;CAS 抢占/超时恢复/重试上限;sync/cron/cli 三模式
Schema 初始化与种子 幂等 bootstrap(目录树 + 8 库 + 22 表 + 默认种子)
ViewCounter 浏览计数 APCu 内存计数 + shutdown 批量落库;无 APCu 静默降级为直写 UPDATE(不崩站)
SearchIndexStore 搜索索引 季度分文件存储,与 business 库物理隔离(P21 瘦身 306MB → 19MB)

2.5 事务与一致性

  • 桶写入用原始 SQL exec('BEGIN')/exec('COMMIT');business 库用 beginTransaction()/commit(),二者不混用;
  • 正文外置红线:先原子写 extern → 再写索引行,绝不允许"索引导入成功但正文丢失"(迁移故障注入已验证);
  • 计数延迟合并:统计/浏览数先走内存/APCu 计数,请求结束时批量写回,把写放大钉死在量化边界。

三、性能实测优势

FlintHub 在 19.2 万帖、5 万用户、235 万搜索索引行的真实数据规模下,经过 P22~P25 系列优化,实测数据如下(均来自真实环境逐查询剖析):

3.1 首页加载:0.11s → 缓存命中 2.3ms

问题 根因 修复 实测效果
首页 0.11s 统计 GROUP BY 对 19.2 万行全表扫描(60s TTL 周期性触发 ~99ms) 永久化统计缓存(去 TTL,仅发帖/回帖失效) 99ms → 2.14ms
后台首页 users 排序 ORDER BY created_at 无索引 → 全表扫描+排序 新增 idx_users_created 26.5ms → 0.05ms
在线人数统计 无 last_activity 索引 + 无缓存 新增索引 + 30s 短缓存 5.94ms → 0.10ms
深翻页(第 12000 页) LIMIT n OFFSET m 线性跳过索引项 keyset 行值比较(游标化) 188ms → 0.36ms
编辑帖子不生效(虚拟主机) 读取链 .bin/.idx 优先,编辑只重写 .txt,旧偏移遮蔽新正文 invalidateArchiveEntry() 作废 .idx 条目回退 .txt 往返实测通过
浏览数恒为 0 APCu 只内存计数,无落库调用点 shutdown 挂接 ViewCounter::flush() 0 → 实时累积

3.2 缓存体系(读降级为拼缓存)

缓存层 机制 命中成本
入口前置缓存(P23/P24) index.php 在 require init.php 之前直接输出 pages/ 缓存并 exit;纯游客 / 有会话 Cookie 但未登录的游客均可命中 ~2.3ms(keep-alive),跳过 Session/DB/插件/在线状态全部引导
页面永久缓存(PageCache) data/runtime/pages/*.html 整页静态化,无 TTL,发帖/回帖主动失效 命中直出
统计永久缓存 Category::getCategoryStats() 聚合缓存(GROUP BY 一次出全部版块数) 2ms 级
版块最新帖快照(P25,Ofstar 借鉴) category_{id}_latest.json,发帖/回帖刷新 零大表查询
在线数据短缓存 online_data.cache.json 30s TTL 7.3ms → 缓存命中
运行时 KV 缓存 Settings 三层缓存(内存 → 文件 → DB) 亚毫秒

3.3 性能设计原则(踩坑教训沉淀)

  • ⚠️ 给统计查询加覆盖索引前必须 EXPLAIN 验证列表查询的规划器选择:曾因 SQLite 误选统计覆盖索引导致 19 万行 TEMP B-TREE 排序(0.1s → 0.3s 回归),已回滚——优先用永久缓存而不是新索引;
  • 写放大硬上限(Ofstar 借鉴):online_users 清理、Session GC 均 LIMIT 5000 分批,防止单次请求卡顿;
  • keyset 深翻页:仅"上一页/下一页"走游标快路径,页码数字直达走 OFFSET(低频可接受),置顶帖纳入行值比较不重不漏;
  • CLI 测量注意:跨进程 warm 渲染有 7~66ms 波动(冷 WAL/杀软扫描),测耗时必须同进程多次取稳态。

四、功能特性

4.1 前台功能

  • 论坛:多版块、发帖/回帖、置顶/精华/高亮、颜色标记、Markdown 编辑器、附件上传(权限随版块)、软删/回收站、深翻页(keyset 游标);
  • 博客:分类、发布、评论、管理;
  • 用户中心:注册/登录(邮箱验证 + 记住我)、个人资料/头像/签名、私信(收件/发件)、积分/等级、用户组与权限;
  • 搜索:自研 bigram 倒排索引,季度分文件存储,支持时间范围过滤;
  • 标签系统:帖子标签、标签页聚合;
  • 投票与 API:帖子投票、图片抓取、验证码、Ajax 上传(htmx + Alpine 前端,fhajax.js/fhstate.js);
  • 主题切换:单模板体系(modern 主题 + 配色变体),后台可传 CSS/切换默认主题。

4.2 后台管理

  • 仪表盘:站点统计、环境信息、在线数据(30s 缓存);
  • 用户管理:列表分页、按关键词/字段/角色/状态查询、编辑(角色/积分/等级/用户组,含唯一管理员保护)、删除级联;
  • 帖子管理:列表分页、按分类筛选、批量删除/批量移动(操作后保留筛选)、编辑、删除;回收站(Trashed)恢复;
  • 版块/博客分类:增删改、排序、删除重置;
  • 标签/等级/用户组/权限:完整后台管理;
  • 设置:基本信息/显示/邮件(SMTP AES 加密)/搜索/任务调度(三模式 + 队列面板 + 手动触发);
  • 数据库维护:SQLite 信息、备份、VACUUM、索引管理;
  • 邮件验证、主题管理、插件管理(激活/停用/卸载/编辑)。

4.3 插件系统(26 个,23 个独立数据库)

FlintHub 插件按「一目录一插件」组织于 plugins/,共 26 个(今日热榜 news_aggregator 不在其列)。其中 23 个插件的数据独立存放于自身目录 plugins/{名}/data/{名}.sqlite,互不依赖、卸载即删,核心库不受插件建表影响;另有 3 个无库插件:本地草稿保护 draft_saver(纯前端 localStorage)、代码仓库 code_repo(仓库目录直读)、图标生成器 icon_generator(生成静态图标资源)。

按插件后台分类列举如下:

  • 社区类(11 个):AI 助手 ai_assistant | 内容审核 content_review | 楼中楼 floor_reply | 版块强制 Tag forum_required_tag | 邀请注册 invite | 社区治理 mod_system(举报中心 + 小黑屋 + 通知联动) | 通知中心 notifications | 帖子收藏 post_favorite | 问答社区 qa | 任务中心 task_center | 用户主页 user_profile
  • 内容类(4 个):站点公告 announcements | 编辑信息 edit_info | 友情链接 friend_links | 单页/链接管理 single_page
  • 娱乐类(6 个):每日签到 daily_checkin | 掷骰子 dice | 勋章中心 medal | 积分商城 points_mall | 猜题对决 quiz_duel | 积分红包 red_packet
  • 系统类(2 个):代码审计 code_audit | SEO 优化 seo

插件通过 Plugin::hook() 钩子系统与核心联动(核心侧实测 37 处调用点,覆盖控制器/视图/init 全链路),启用经 activate/deactivate 完成建表与清理,无致命缺索引联表查询。


五、部署形态与兼容性

5.1 三种队列调度模式(后台可切换)

模式 适用场景 行为
sync 同步直写(默认) 个人测试 / 廉价虚拟主机 发帖/回帖成功后页面等待索引与统计更新完毕再返回,数据 100% 实时
cron 定时触发 有 Crontab 权限但无法常驻 PHP 进程 发帖后任务入 SQLite 队列,由 cli/worker.php --once 或 cron_trigger.php(web 入口,带文件锁防并发)批量消费
cli 常驻消费 Linux VPS / 独立服务器(Supervisor) 后台常驻 cli/worker.php 实时消费,页面响应最快

5.2 虚拟主机适配(无 SSH / 无 APCu 环境)

  • 无 APCu 自动降级:浏览计数、extern 正文缓存静默降级为直写/直读,不崩站(白皮书红线要求);
  • 无 crontab:可用 cron_trigger.php web 触发(仅 cron 模式生效,文件锁防重入);
  • 编辑不生效问题已修复:虚拟主机场景 .idx 旧偏移遮蔽新正文 → invalidateArchiveEntry() 回退 .txt;
  • 纯 SQLite 部署:无需 MySQL、无需安装扩展(PDO_SQLITE 内置),data/ 目录可写即可。

5.3 环境要求

项 要求
PHP ≥ 8.0(SQLite 3.33+,实测 8.0.2)
Web 服务器 Nginx / Apache / php -S 均可(附 nginx-server.conf)
扩展 PDO_SQLITE(内置);APCu 可选(有则更快,无则降级)
安装 浏览器访问 install.php → 环境检测 → 建管理员 → 完成

六、工程质量与安全

6.1 迁移与数据安全红线

  • 正文剥离红线:旧 MySQL → SplitDB 迁移时正文 MEDIUMTEXT 必须成功剥离为 extern/ 文件;失败则整体回滚,绝不允许「索引导入成功但正文丢失」(故障注入已验证);
  • 迁移顺序红线:先原子写 extern → 再写索引行,三处落盘(extern + 桶 + 索引)完整性校验;
  • SQLite 变量上限 32766:批量 IN/NOT IN 必须 array_chunk 分批(900/批安全),NOT IN 分批先算孤儿集防误删全表。

6.2 安全防护

层 措施
SQL 注入 全站参数绑定 + Model 层 buildWhere 白名单字符校验 + ORDER BY sanitize
CSRF 前后台表单 Token 校验(Csrf helper)
XSS 视图输出统一 $this->e() 转义
会话 SQLite session handler + 独立连接防游标冲突 + session_regenerate 防固定 + cookie_secure/samesite
上传 扩展名白名单 + 5MB 上限 + 权限随版块
后台 管理员二次密码验证(30 分钟超时)+ 唯一管理员降级/删除保护
审计 AuditLog 全链路记录(删除/移动/设置等管理操作)

6.3 自动化测试(冒烟)

  • cli/smoke_install.php:空目录安装全链路,30/30 通过;
  • cli/smoke_migrate.php:迁移全链路(含红线故障注入),21/21 通过;
  • 引擎冒烟:DBFactory / IDGenerator / ShardRouter / ExternStorage / Queue / Schema / ViewCounter 各独立脚本;
  • 全部交付文件 php -l 校验 + update/ 镜像 fc /b 逐字节比对。

6.4 已知取舍与注意事项

  • 浏览数为 0 是历史数据(旧库从未落库),修复后新浏览量实时累积;回填需另找数据源;
  • 改视图后必须失效 data/runtime/pages/*.html 静态缓存(发帖/回帖自动失效,视图改动本身不会);
  • 前置缓存仅游客命中,已登录用户走完整管线(个性化内容不缓存);
  • MAIL_PASS_KEY 为 AES 密钥(含历史 SoSite 字样),勿改(改则已存 SMTP 密码无法解密)。

本文档完。FlintHub 1.0 —— 用纯 SQLite 分片引擎实现 PHP 社区系统的极致轻量与可靠性能。

最後由 flinthub 於 2026-09-05 14:53 編輯
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 425 次 | 回覆 6 次

全部回覆 (6)

🌲Lv.3 初级 ⭐️ 新访客
2026-08-27 14:07:09
看介绍不错,希望能够提供下载测试一下。
#1 樓
👑Lv.11 元老 🌏 正式会员
2026-08-27 14:09:35
还在打磨中,暂时不提供下载。
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
#2 樓
🌟Lv.6 资深 🌛 见习会员
2026-08-27 18:28:21
很希望能够尽快用上这个程序。
我就是我,不一样的烟火🎇
#3 樓
🌲Lv.3 初级 🌛 见习会员
2026-08-27 18:32:19
尽快搞一下吧,很期待。
#4 樓
👑Lv.11 元老 🌏 正式会员
2026-08-27 18:33:48
需要慢慢打磨,急不得,即使到能用的地步,也需要积分来下载,加油搞积分吧。
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
#5 樓
👑Lv.11 元老 🌏 正式会员
2026-09-03 10:12:32
遵循本心好难,老想着把程序做到面面俱到,这样的结果可能导致程序越来越臃肿。
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
#6 樓

請 登入