修改成redis
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag" // 命令行参数解析
|
||||
"fmt" // 格式化(搜索服务端口)
|
||||
"log" // 日志输出
|
||||
@@ -17,12 +18,15 @@ import (
|
||||
"os/signal" // 信号捕获
|
||||
"path/filepath" // 路径处理
|
||||
"syscall" // 系统调用(SIGTERM)
|
||||
"time" // 时间(刷盘间隔)
|
||||
|
||||
"sese-engine/analyzer" // 文本分析和关键词提取
|
||||
"sese-engine/backlink" // 反向链接(繁荣值)计算
|
||||
"sese-engine/config" // 全局配置
|
||||
"sese-engine/crawler" // BFS 爬虫
|
||||
"sese-engine/info" // info 服务(繁荣表、调整表、屏蔽词)
|
||||
"sese-engine/mysql" // MySQL 数据库连接
|
||||
"sese-engine/redis" // Redis 连接
|
||||
"sese-engine/search" // 搜索服务器(内嵌收获服务)
|
||||
"sese-engine/storage" // 持久化存储
|
||||
)
|
||||
@@ -138,13 +142,44 @@ func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
log.Printf("sese-engine starting storage=%s entry=%s", *storageDir, *entryURL)
|
||||
|
||||
// ---- 1. 存储层:打开 bbolt 数据库 ----
|
||||
db, err := storage.Open(*storageDir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open storage: %v", err)
|
||||
// ---- 1. Redis 连接(高性能内存存储)----
|
||||
if err := redis.Open(); err != nil {
|
||||
log.Fatalf("failed to open redis: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
db.StartWriteFlusher() // 启动异步写缓冲后台刷盘
|
||||
defer redis.Close()
|
||||
|
||||
// ---- 1.1 MySQL 连接(持久化存储,默认关闭)----
|
||||
var flusher *mysql.Flusher
|
||||
if config.MySQLEnabled() {
|
||||
if err := mysql.Open(); err != nil {
|
||||
log.Fatalf("failed to open mysql: %v", err)
|
||||
}
|
||||
defer mysql.Close()
|
||||
|
||||
// 从 MySQL 恢复数据到 Redis(如 Redis 数据丢失)
|
||||
// 仅当 Redis 为空时才执行恢复,避免覆盖已有数据
|
||||
ctx := context.Background()
|
||||
size, _ := redis.Client.DBSize(ctx).Result()
|
||||
if size > 0 {
|
||||
log.Printf("[mysql-restore] Redis has %d keys, skipping restore", size)
|
||||
} else if err := mysql.RestoreFromMySQLToRedis(redis.Client); err != nil {
|
||||
log.Printf("[mysql-restore] warning: %v", err)
|
||||
}
|
||||
|
||||
// MySQL 刷盘器:定期将 Redis 数据刷到 MySQL
|
||||
flusher = mysql.NewFlusher(redis.Client, 5*time.Minute, 1000)
|
||||
flusher.Start()
|
||||
defer flusher.Stop()
|
||||
} else {
|
||||
log.Println("[mysql] disabled in config, skipping MySQL init")
|
||||
}
|
||||
|
||||
// ---- 1.3 存储层:初始化 Redis 存储 ----
|
||||
store := storage.NewRedisStoreV2()
|
||||
if err := store.Init(); err != nil {
|
||||
log.Fatalf("failed to init redis store: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
// ---- 2. Info 服务:加载繁荣表、调整表和屏蔽词 ----
|
||||
infoSvc := info.New(*storageDir)
|
||||
@@ -158,7 +193,7 @@ func main() {
|
||||
defer anal.Close()
|
||||
|
||||
// ---- 4. 搜索服务器(默认 :80):对外提供搜索 API,同时内嵌收获服务(统一端口)
|
||||
searchSrv := search.New(db, infoSvc, anal)
|
||||
searchSrv := search.New(store, infoSvc, anal)
|
||||
go func() {
|
||||
addr := fmt.Sprintf(":%d", config.SearchServerPort())
|
||||
if err := searchSrv.ListenAndServe(addr, config.UnixSocket()); err != nil {
|
||||
@@ -167,14 +202,14 @@ func main() {
|
||||
}()
|
||||
|
||||
// ---- 6. 反向链接计算器:每 48 小时运行一次 ----
|
||||
bl := backlink.New(db, *storageDir)
|
||||
bl := backlink.New(store, *storageDir)
|
||||
searchSrv.SetBacklinkRunner(bl)
|
||||
go bl.Run()
|
||||
|
||||
// ---- 7. 爬虫:从入口 URL 开始 BFS 爬取 ----
|
||||
// 从 info 服务获取繁荣表快照,用于调度优先级决策
|
||||
prosperMap := infoSvc.ProsperMap()
|
||||
crawl := crawler.New(db, anal, prosperMap)
|
||||
crawl := crawler.New(store, anal, prosperMap)
|
||||
searchSrv.SetCrawler(crawl) // 注入爬虫用于 Priority URL 立即触发
|
||||
go crawl.Run(*entryURL, config.MaxEpoch())
|
||||
|
||||
@@ -194,8 +229,12 @@ func main() {
|
||||
crawl.WaitUntilStopped()
|
||||
log.Println("crawler stopped")
|
||||
|
||||
// 最后刷盘,确保数据不丢失
|
||||
log.Println("flushing index...")
|
||||
// 最后刷盘(Redis → Disk,条件刷 MySQL),确保数据不丢失
|
||||
log.Println("flushing index to disk...")
|
||||
searchSrv.Flush()
|
||||
if flusher != nil {
|
||||
log.Println("flushing data to mysql...")
|
||||
flusher.RunAll() // 同步执行一次 MySQL 刷盘
|
||||
}
|
||||
log.Println("shutdown complete")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user