feat(core): optimize performance and reliability through batching and redis-backed unread counts
This commit introduces several significant architectural improvements to enhance system performance, scalability, and reliability:
- **Performance Optimization (N+1 Problem Resolution)**: Implemented batching mechanisms across `MessageHandler`, `ChatService`, `GroupService`, `MessageService`, and `UserService`. This replaces multiple individual database/cache queries with single batch operations for fetching unread counts, last messages, participants, and user information.
- **Enhanced Unread Count Management**: Migrated unread count tracking to a Redis Hash-based approach (`unread#️⃣{userID}`). This allows for atomic increments/decrements and efficient retrieval of both individual conversation unread counts and total unread counts for a user.
- **Improved Message Sequencing**: Integrated Redis-based sequence (`seq`) pre-allocation for messages to ensure strict ordering and reduce database contention during high-concurrency message creation.
- **Push Service Reliability**: Refactored the push notification system to include persistent `PushRecord` tracking. Added a recovery mechanism (`recoverPendingPushes`) to reload pending notifications from the database upon service startup, ensuring better delivery guarantees.
- **WebSocket Reliability**: Updated the WebSocket hub to move away from in-memory history replay in favor of a client-driven synchronization model (`sync_required` event and `ack` handling), reducing memory overhead and improving connection stability.
- **Cache Layer Enhancements**: Added `HIncrBy` and `IncrBySeq` to the `Cache` interface and its implementations (`RedisCache`, `LayeredCache`) to support the new unread and sequence management logic.
This commit is contained in:
12
internal/cache/keys.go
vendored
12
internal/cache/keys.go
vendored
@@ -26,6 +26,8 @@ const (
|
||||
PrefixUnreadSystem = "unread:system"
|
||||
PrefixUnreadConversation = "unread:conversation"
|
||||
PrefixUnreadDetail = "unread:detail"
|
||||
PrefixUnreadHash = "unread:hash"
|
||||
PrefixUnreadTotal = "unread:total"
|
||||
|
||||
// 用户相关
|
||||
PrefixUserInfo = "users:info"
|
||||
@@ -118,6 +120,16 @@ func UnreadDetailKey(userID, conversationID string) string {
|
||||
return fmt.Sprintf("%s:%s:%s", PrefixUnreadDetail, userID, conversationID)
|
||||
}
|
||||
|
||||
// UnreadHashKey 生成用户未读数 Hash 缓存键
|
||||
func UnreadHashKey(userID string) string {
|
||||
return fmt.Sprintf("%s:%s", PrefixUnreadHash, userID)
|
||||
}
|
||||
|
||||
// UnreadTotalKey 生成用户总未读数计数器键
|
||||
func UnreadTotalKey(userID string) string {
|
||||
return fmt.Sprintf("%s:%s", PrefixUnreadTotal, userID)
|
||||
}
|
||||
|
||||
// UserInfoKey 生成用户信息缓存键
|
||||
func UserInfoKey(userID string) string {
|
||||
return fmt.Sprintf("%s:%s", PrefixUserInfo, userID)
|
||||
|
||||
Reference in New Issue
Block a user