1
This commit is contained in:
parent
997e50c6e0
commit
7226255877
141
MONGODB_INDEXES.md
Normal file
141
MONGODB_INDEXES.md
Normal 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. **生产环境**:在生产环境中创建索引可能需要考虑对性能的影响,建议在低峰期执行
|
||||||
@ -30,8 +30,7 @@ const GenerationResultSchema: Schema = new Schema({
|
|||||||
task_id: {
|
task_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
unique: true,
|
unique: true
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
task_type: {
|
task_type: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -40,8 +39,7 @@ const GenerationResultSchema: Schema = new Schema({
|
|||||||
},
|
},
|
||||||
server_id: {
|
server_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -66,25 +64,15 @@ const GenerationResultSchema: Schema = new Schema({
|
|||||||
},
|
},
|
||||||
created_at: {
|
created_at: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: () => Math.floor(Date.now() / 1000),
|
default: () => Math.floor(Date.now() / 1000)
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
expires_at: {
|
expires_at: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true
|
||||||
index: true
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
collection: 'jimeng_free_generation_results',
|
collection: 'jimeng_free_generation_results',
|
||||||
timestamps: false // 使用自定义时间戳
|
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);
|
export default mongoose.model<IGenerationResult>('GenerationResult', GenerationResultSchema);
|
||||||
@ -59,8 +59,7 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
task_id: {
|
task_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
unique: true,
|
unique: true
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
task_type: {
|
task_type: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -69,8 +68,7 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
},
|
},
|
||||||
server_id: {
|
server_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
original_params: {
|
original_params: {
|
||||||
model: String,
|
model: String,
|
||||||
@ -100,8 +98,7 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
enum: ['pending', 'processing', 'polling', 'completed', 'failed'],
|
enum: ['pending', 'processing', 'polling', 'completed', 'failed'],
|
||||||
default: 'pending',
|
default: 'pending'
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
retry_count: {
|
retry_count: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -112,8 +109,7 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
default: 3
|
default: 3
|
||||||
},
|
},
|
||||||
next_poll_at: {
|
next_poll_at: {
|
||||||
type: Number,
|
type: Number
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
poll_interval: {
|
poll_interval: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -125,8 +121,7 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
},
|
},
|
||||||
created_at: {
|
created_at: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: () => Math.floor(Date.now() / 1000),
|
default: () => Math.floor(Date.now() / 1000)
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
updated_at: {
|
updated_at: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -141,12 +136,4 @@ const GenerationTaskSchema: Schema = new Schema({
|
|||||||
timestamps: false // 使用自定义时间戳
|
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);
|
export default mongoose.model<IGenerationTask>('GenerationTask', GenerationTaskSchema);
|
||||||
@ -16,8 +16,7 @@ const JimengServerSchema: Schema = new Schema({
|
|||||||
server_id: {
|
server_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
unique: true,
|
unique: true
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
server_name: {
|
server_name: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -33,8 +32,7 @@ const JimengServerSchema: Schema = new Schema({
|
|||||||
},
|
},
|
||||||
last_heartbeat: {
|
last_heartbeat: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0
|
||||||
index: true
|
|
||||||
},
|
},
|
||||||
heartbeat_interval: {
|
heartbeat_interval: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -53,8 +51,4 @@ const JimengServerSchema: Schema = new Schema({
|
|||||||
timestamps: false // 使用自定义时间戳
|
timestamps: false // 使用自定义时间戳
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建索引
|
|
||||||
JimengServerSchema.index({ server_id: 1 });
|
|
||||||
JimengServerSchema.index({ is_active: 1, last_heartbeat: 1 });
|
|
||||||
|
|
||||||
export default mongoose.model<IJimengServer>('JimengServer', JimengServerSchema);
|
export default mongoose.model<IJimengServer>('JimengServer', JimengServerSchema);
|
||||||
@ -55,7 +55,6 @@ export class HeartbeatService {
|
|||||||
|
|
||||||
private getLocalIP(): string | null {
|
private getLocalIP(): string | null {
|
||||||
try {
|
try {
|
||||||
const os = require('os');
|
|
||||||
const interfaces = os.networkInterfaces();
|
const interfaces = os.networkInterfaces();
|
||||||
|
|
||||||
// 优先查找非回环的IPv4地址
|
// 优先查找非回环的IPv4地址
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user