# mysqlredis **Repository Path**: fredgo/mysqlredis ## Basic Information - **Project Name**: mysqlredis - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-07 - **Last Updated**: 2025-11-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MySQL-Redis 一个高性能的 MySQL 和 Redis 集成库,提供便捷的数据库操作、缓存管理和事务支持。 ## ✨ 特性 - 🚀 **高性能**: 使用 Redis 原生命令优化,支持批量操作 - 🔒 **事务支持**: MySQL 事务与 Redis 缓存一致性处理 - 🔐 **分布式锁**: 内置分布式锁,防止并发问题 - 📊 **监控**: 连接池监控、缓存统计、健康检查、Prometheus metrics - 🛡️ **错误处理**: 完善的错误处理和重试机制 - ⚙️ **配置灵活**: 支持配置文件和环境变量 - 🔄 **自动重试**: 智能重试机制,提高可靠性 - ⏱️ **超时控制**: 所有操作支持超时控制 - 📝 **结构化日志**: 支持结构化日志记录和慢查询日志 - 🔌 **连接管理**: 连接重连和健康检查机制 - 🌍 **地理位置**: Redis GEO 操作封装,支持附近搜索 - 🔑 **幂等性**: 内置幂等性检查,防止重复请求 - 💓 **心跳管理**: 心跳检测和自动清理 - 📦 **集合操作**: 有序集合和集合操作封装 - 📏 **距离计算**: 地理位置距离计算工具 ## 📦 安装 ```bash go get gitee.com/fredgo/mysqlredis ``` ## 🚀 快速开始 ### 1. 基本使用 ```go package main import ( "context" "log" mysql_redis "gitee.com/fredgo/mysqlredis" ) func main() { // 从配置文件创建客户端 client, err := mysql_redis.NewFromFile("config.yaml") if err != nil { log.Fatal(err) } defer client.Close(context.Background()) ctx := context.Background() // 查询数据 record, err := client.FindByID(ctx, "users", 1) if err != nil { log.Fatal(err) } user := record.Map() log.Printf("User: %v", user) } ``` ### 2. 配置文件示例 创建 `config.yaml`: ```yaml mysql: host: "127.0.0.1" port: "3306" user: "root" pass: "password" name: "mydb" charset: "utf8mb4" maxIdle: 10 maxOpen: 100 redis: address: "127.0.0.1:6379" pass: "" db: 0 poolSize: 10 cache: enableRedisAdapter: true defaultCacheDuration: 5m ``` ### 3. 使用缓存 ```go // 带缓存的查询 record, err := client.FindByIDWithCache(ctx, "users", 1, 5*time.Minute) // 手动缓存操作 cacheHelper := client.NewCacheHelper() cacheHelper.Set(ctx, "key", "value", 10*time.Minute) value, _ := cacheHelper.Get(ctx, "key") ``` ### 4. 事务操作 ```go err := client.TransactionWithCache(ctx, mysql_redis.TransactionOption{ CacheKeysToDelete: []string{"user:1", "user:list"}, }, func(ctx context.Context, tx helps.TX) error { // 执行数据库操作 _, err := tx.Update(ctx, "users", map[string]interface{}{ "name": "New Name", }, "id = ?", 1) return err }) ``` ### 5. 分布式锁 ```go lock, err := client.AcquireDistributedLock(ctx, "lock:key", 10*time.Second) if err != nil { log.Fatal(err) } defer lock.Release(ctx) // 执行需要锁的操作 ``` ## 📚 核心功能 ### 数据库操作 ```go // 查询构建器 qb := client.NewQueryBuilder("users") record, err := qb.Where("id = ?", 1).Cache(5*time.Minute).One() // 便捷方法 dbHelper := client.NewDBHelper() record, _ := dbHelper.FindOne(ctx, "users", map[string]interface{}{"id": 1}) records, _ := dbHelper.FindAll(ctx, "users", map[string]interface{}{"status": "active"}) page, _ := dbHelper.FindPage(ctx, "users", map[string]interface{}{}, 1, 20) ``` ### 缓存操作 ```go cacheHelper := client.NewCacheHelper() // 基本操作 cacheHelper.Set(ctx, "key", "value", 10*time.Minute) value, _ := cacheHelper.Get(ctx, "key") cacheHelper.Delete(ctx, "key1", "key2") // 高级操作 cacheHelper.Increment(ctx, "counter", 1) cacheHelper.SetIfNotExists(ctx, "key", "value", 10*time.Minute) // 批量操作 items := map[string]interface{}{ "key1": "value1", "key2": "value2", } cacheHelper.BatchSet(ctx, items, 10*time.Minute) ``` ### 健康检查 ```go // 检查健康状态 status, err := client.HealthCheck(ctx) if err != nil { log.Fatal(err) } if status.Overall { log.Println("系统健康") } else { log.Printf("MySQL: %s, Redis: %s", status.MySQL.Status, status.Redis.Status) } // 获取连接统计 stats := client.GetConnectionStats(ctx) log.Printf("MySQL 连接: %d 打开, %d 使用中", stats.MySQL.OpenConnections, stats.MySQL.InUse) ``` ### 缓存预热 ```go // 预热缓存 items := []mysql_redis.WarmupItem{ { Key: "user:1", GetValue: func() (interface{}, error) { return client.FindByID(ctx, "users", 1) }, Duration: 10 * time.Minute, }, } result, _ := client.WarmupCache(ctx, items, 10) log.Printf("预热完成: %d/%d 成功", result.Success, result.Total) ``` ## 🔧 配置选项 ### MySQL 配置 ```go type MySQLConfig struct { Host string // 数据库主机 Port string // 端口 User string // 用户名 Pass string // 密码 Name string // 数据库名 Charset string // 字符集,默认 utf8mb4 MaxIdleConnCount int // 最大空闲连接数 MaxOpenConnCount int // 最大打开连接数 MaxConnLifeTime time.Duration // 连接最大生存时间 QueryTimeout time.Duration // 查询超时 ExecTimeout time.Duration // 执行超时 Debug bool // 调试模式 } ``` ### Redis 配置 ```go type RedisConfig struct { Address string // Redis 地址 Pass string // 密码 Db int // 数据库编号 PoolSize int // 连接池大小 MinIdle int // 最小空闲连接数 DialTimeout time.Duration // 连接超时 ReadTimeout time.Duration // 读超时 WriteTimeout time.Duration // 写超时 } ``` ### 超时控制 ```go // 为查询操作添加超时 ctx, cancel := client.WithQueryTimeout(ctx) defer cancel() record, err := client.FindByID(ctx, "users", 1) // 执行带超时的操作 err := client.QueryWithTimeout(ctx, 5*time.Second, func(ctx context.Context) error { // 执行查询 return nil }) ``` ### 指标收集 ```go // 创建指标收集器 collector := client.NewMetricsCollector() // 记录操作 collector.RecordDBQuery(duration) collector.RecordCacheHit(duration) // 获取指标 metrics := collector.GetMetrics() log.Printf("缓存命中率: %.2f%%", metrics.CacheHitRate*100) // 导出 Prometheus 格式 promMetrics := collector.PrometheusMetrics() // 可以暴露给 Prometheus ``` ### 结构化日志 ```go // 创建结构化日志记录器 logger := client.GetStructuredLogger() if logger != nil { logger.Info(ctx, "User created", map[string]interface{}{ "user_id": 123, "username": "john", }) logger.Error(ctx, "Failed to create user", err, map[string]interface{}{ "user_id": 123, }) } // 慢查询日志 config := mysql_redis.DefaultSlowQueryConfig() timer := client.StartQueryTimer("SELECT * FROM users", config) // ... 执行查询 ... timer.End(ctx) // 自动记录慢查询 ``` ### 连接重连 ```go // 创建重连管理器 config := mysql_redis.DefaultReconnectConfig() reconnectManager := client.NewReconnectManager(config) // 启动自动重连监控 ctx := context.Background() reconnectManager.Start(ctx) defer reconnectManager.Stop() // 确保连接可用 err := client.EnsureConnected(ctx) ``` ## ⚠️ 注意事项 1. **事务一致性**: MySQL 和 Redis 无法参与真正的分布式事务,存在潜在一致性问题。建议使用 `TransactionWithCacheSafe` 方法。 2. **连接管理**: 确保在使用完毕后调用 `Close()` 方法关闭连接。建议使用重连管理器自动处理连接问题。 3. **错误处理**: 所有操作都可能返回错误,请务必检查错误。 4. **缓存失效**: 更新数据后记得失效相关缓存,使用 `TransactionWithCache` 可以自动处理。 5. **超时设置**: 建议为所有操作设置合理的超时时间,避免长时间阻塞。 6. **监控和日志**: 生产环境建议启用指标收集和结构化日志,便于监控和排查问题。 ### 地理位置操作 ```go // 添加地理位置 locations := []mysql_redis.GeoLocation{ {Longitude: 116.3974, Latitude: 39.9093, Member: "req:1"}, } client.GeoAdd(ctx, "jz:req:geo", locations...) // 查询附近的需求 results, _ := client.GeoRadius(ctx, "jz:req:geo", 116.3974, 39.9093, 10, "km", mysql_redis.WithDistance(), mysql_redis.WithCount(10), ) ``` ### 幂等性检查 ```go checker := client.NewIdempotentChecker("jz:idempotent:") success, _ := checker.CheckAndSet(ctx, requestID, 5*time.Minute) if !success { return errors.New("重复请求") } ``` ### 心跳管理 ```go manager := client.NewHeartbeatManager("jz:worker:heartbeat:", 60*time.Second) manager.Update(ctx, workerID) alive, _ := manager.IsAlive(ctx, workerID) ``` ### 锁操作 ```go lockManager := client.NewLockManager("jz:req:lock:") err := lockManager.WithLock(ctx, requirementID, 10*time.Second, func() error { // 执行需要锁的操作 return nil }) ``` ### 距离计算 ```go distance := mysql_redis.CalculateDistance(lat1, lon1, lat2, lon2) within := mysql_redis.IsWithinDistance(lat1, lon1, lat2, lon2, 10.0) ``` ## 📖 更多示例 - [基本使用示例](examples/basic_usage.go) - [高级功能示例](examples/advanced_usage.go) - [JZ 项目集成示例](examples/jz_usage.go) - [完整应用示例](../example/main.go) - [JZ 项目集成指南](JZ_INTEGRATION.md) ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📄 许可证 [请添加许可证信息] ## 🔗 相关链接 - [文档结构说明](doc/FILE_STRUCTURE.md) - [生产就绪性评估](PRODUCTION_READINESS.md)