This commit is contained in:
jonathang4 2025-08-27 17:11:05 +08:00
parent 997e50c6e0
commit 7226255877
5 changed files with 152 additions and 43 deletions

141
MONGODB_INDEXES.md Normal file
View File

@ -0,0 +1,141 @@
# MongoDB 索引创建指南
本项目使用 MongoDB 作为数据库,为了确保良好的查询性能,需要手动创建以下索引。
## 连接到 MongoDB
```bash
# 连接到 MongoDB
mongo mongodb://localhost:27017/jimeng-api
# 或者使用 MongoDB Compass 等图形工具
```
## 需要创建的索引
### 1. 生成任务表 (jimeng_free_generation_tasks)
```javascript
// 基础索引
db.jimeng_free_generation_tasks.createIndex({ "task_id": 1 }, { unique: true });
db.jimeng_free_generation_tasks.createIndex({ "server_id": 1 });
db.jimeng_free_generation_tasks.createIndex({ "status": 1 });
db.jimeng_free_generation_tasks.createIndex({ "created_at": 1 });
db.jimeng_free_generation_tasks.createIndex({ "next_poll_at": 1 });
// 复合索引 - 用于轮询查询优化
db.jimeng_free_generation_tasks.createIndex({
"server_id": 1,
"status": 1,
"next_poll_at": 1
});
// 复合索引 - 用于服务器负载查询
db.jimeng_free_generation_tasks.createIndex({
"server_id": 1,
"created_at": 1
});
```
### 2. 生成结果表 (jimeng_free_generation_results)
```javascript
// 基础索引
db.jimeng_free_generation_results.createIndex({ "task_id": 1 }, { unique: true });
db.jimeng_free_generation_results.createIndex({ "server_id": 1 });
db.jimeng_free_generation_results.createIndex({ "created_at": 1 });
// TTL索引 - 自动清理过期记录
db.jimeng_free_generation_results.createIndex({
"expires_at": 1
}, {
expireAfterSeconds: 0
});
// 复合索引
db.jimeng_free_generation_results.createIndex({
"server_id": 1,
"created_at": 1
});
```
### 3. 服务器心跳表 (jimeng_servers)
```javascript
// 基础索引
db.jimeng_servers.createIndex({ "server_id": 1 }, { unique: true });
db.jimeng_servers.createIndex({ "last_heartbeat": 1 });
// 复合索引 - 用于查询在线服务器
db.jimeng_servers.createIndex({
"is_active": 1,
"last_heartbeat": 1
});
```
## 一键执行脚本
将以下内容保存为 `create_indexes.js` 文件,然后执行:
```javascript
// create_indexes.js
print("开始创建 jimeng-free-api 数据库索引...");
// 生成任务表索引
db = db.getSiblingDB('jimeng-api');
print("创建生成任务表索引...");
db.jimeng_free_generation_tasks.createIndex({ "task_id": 1 }, { unique: true });
db.jimeng_free_generation_tasks.createIndex({ "server_id": 1 });
db.jimeng_free_generation_tasks.createIndex({ "status": 1 });
db.jimeng_free_generation_tasks.createIndex({ "created_at": 1 });
db.jimeng_free_generation_tasks.createIndex({ "next_poll_at": 1 });
db.jimeng_free_generation_tasks.createIndex({ "server_id": 1, "status": 1, "next_poll_at": 1 });
db.jimeng_free_generation_tasks.createIndex({ "server_id": 1, "created_at": 1 });
print("创建生成结果表索引...");
db.jimeng_free_generation_results.createIndex({ "task_id": 1 }, { unique: true });
db.jimeng_free_generation_results.createIndex({ "server_id": 1 });
db.jimeng_free_generation_results.createIndex({ "created_at": 1 });
db.jimeng_free_generation_results.createIndex({ "expires_at": 1 }, { expireAfterSeconds: 0 });
db.jimeng_free_generation_results.createIndex({ "server_id": 1, "created_at": 1 });
print("创建服务器心跳表索引...");
db.jimeng_servers.createIndex({ "server_id": 1 }, { unique: true });
db.jimeng_servers.createIndex({ "last_heartbeat": 1 });
db.jimeng_servers.createIndex({ "is_active": 1, "last_heartbeat": 1 });
print("所有索引创建完成!");
```
执行命令:
```bash
mongo mongodb://localhost:27017/jimeng-api create_indexes.js
```
## 验证索引
创建完成后,可以验证索引是否正确创建:
```javascript
// 查看所有集合的索引
db.jimeng_free_generation_tasks.getIndexes();
db.jimeng_free_generation_results.getIndexes();
db.jimeng_servers.getIndexes();
```
## 性能说明
- **唯一索引**:确保 task_id 和 server_id 的唯一性
- **复合索引**:优化多字段查询,特别是轮询任务时的复杂查询
- **TTL 索引**:自动清理过期的结果记录,释放存储空间
- **时间索引**:加速基于时间的查询和排序
这些索引的创建顺序不影响功能,但建议按照文档顺序执行以确保最佳性能。
## 注意事项
1. **数据库名称**:请根据实际使用的数据库名称调整脚本中的 `jimeng-api`
2. **连接地址**:请根据实际的 MongoDB 连接地址调整命令
3. **权限要求**:执行索引创建需要数据库的写权限
4. **生产环境**:在生产环境中创建索引可能需要考虑对性能的影响,建议在低峰期执行

View File

@ -30,8 +30,7 @@ const GenerationResultSchema: Schema = new Schema({
task_id: {
type: String,
required: true,
unique: true,
index: true
unique: true
},
task_type: {
type: String,
@ -40,8 +39,7 @@ const GenerationResultSchema: Schema = new Schema({
},
server_id: {
type: String,
required: true,
index: true
required: true
},
status: {
type: String,
@ -66,25 +64,15 @@ const GenerationResultSchema: Schema = new Schema({
},
created_at: {
type: Number,
default: () => Math.floor(Date.now() / 1000),
index: true
default: () => Math.floor(Date.now() / 1000)
},
expires_at: {
type: Number,
required: true,
index: true
required: true
}
}, {
collection: 'jimeng_free_generation_results',
timestamps: false // 使用自定义时间戳
});
// 创建索引
GenerationResultSchema.index({ task_id: 1 });
GenerationResultSchema.index({ expires_at: 1 }); // 用于过期清理
GenerationResultSchema.index({ server_id: 1, created_at: 1 });
// 设置TTL索引自动清理过期记录
GenerationResultSchema.index({ expires_at: 1 }, { expireAfterSeconds: 0 });
export default mongoose.model<IGenerationResult>('GenerationResult', GenerationResultSchema);

View File

@ -59,8 +59,7 @@ const GenerationTaskSchema: Schema = new Schema({
task_id: {
type: String,
required: true,
unique: true,
index: true
unique: true
},
task_type: {
type: String,
@ -69,8 +68,7 @@ const GenerationTaskSchema: Schema = new Schema({
},
server_id: {
type: String,
required: true,
index: true
required: true
},
original_params: {
model: String,
@ -100,8 +98,7 @@ const GenerationTaskSchema: Schema = new Schema({
type: String,
required: true,
enum: ['pending', 'processing', 'polling', 'completed', 'failed'],
default: 'pending',
index: true
default: 'pending'
},
retry_count: {
type: Number,
@ -112,8 +109,7 @@ const GenerationTaskSchema: Schema = new Schema({
default: 3
},
next_poll_at: {
type: Number,
index: true
type: Number
},
poll_interval: {
type: Number,
@ -125,8 +121,7 @@ const GenerationTaskSchema: Schema = new Schema({
},
created_at: {
type: Number,
default: () => Math.floor(Date.now() / 1000),
index: true
default: () => Math.floor(Date.now() / 1000)
},
updated_at: {
type: Number,
@ -141,12 +136,4 @@ const GenerationTaskSchema: Schema = new Schema({
timestamps: false // 使用自定义时间戳
});
// 创建复合索引 - 用于轮询查询
GenerationTaskSchema.index({ server_id: 1, status: 1, next_poll_at: 1 });
// 创建其他索引
GenerationTaskSchema.index({ task_id: 1 });
GenerationTaskSchema.index({ created_at: 1 });
GenerationTaskSchema.index({ updated_at: 1 });
export default mongoose.model<IGenerationTask>('GenerationTask', GenerationTaskSchema);

View File

@ -16,8 +16,7 @@ const JimengServerSchema: Schema = new Schema({
server_id: {
type: String,
required: true,
unique: true,
index: true
unique: true
},
server_name: {
type: String,
@ -33,8 +32,7 @@ const JimengServerSchema: Schema = new Schema({
},
last_heartbeat: {
type: Number,
default: 0,
index: true
default: 0
},
heartbeat_interval: {
type: Number,
@ -53,8 +51,4 @@ const JimengServerSchema: Schema = new Schema({
timestamps: false // 使用自定义时间戳
});
// 创建索引
JimengServerSchema.index({ server_id: 1 });
JimengServerSchema.index({ is_active: 1, last_heartbeat: 1 });
export default mongoose.model<IJimengServer>('JimengServer', JimengServerSchema);

View File

@ -55,7 +55,6 @@ export class HeartbeatService {
private getLocalIP(): string | null {
try {
const os = require('os');
const interfaces = os.networkInterfaces();
// 优先查找非回环的IPv4地址