package redisController import ( "appPlatform/overall/publicmethod" "context" "fmt" "sort" "github.com/gin-gonic/gin" "github.com/redis/go-redis/v9" ) /* * @ 作者: 秦东 @ 时间: 2023-11-13 14:27:45 @ 功能: 测试数据库链接 @ 参数 # @ 返回值 # @ 方法原型 # */ func (a *ApiMethod) TestRedisLink(c *gin.Context) { var redisConfig RedisConfig err := c.ShouldBindJSON(&redisConfig) if err != nil { publicmethod.Result(10001, err, c) return } if redisConfig.Ip == "" { redisConfig.Ip = "127.0.0.1" } if redisConfig.Port == 0 { redisConfig.Port = 6379 } var redisDbConst RunOneRedis redisDbConst.Ip = redisConfig.Ip redisDbConst.Port = redisConfig.Port redisDbConst.Pwd = redisConfig.Pwd redisDbConst.DbName = 10 redisDb := redisDbConst.OpenRedis() // pingLink, err := redisDb.Ping(context.Background()).Result() _, err = redisDb.Ping(context.Background()).Result() redisRunDb := InitRedis(redisDb) redisCont, redisErr := redisRunDb.ConfigGet("databases") // sendData := publicmethod.MapOut[string]() // sendData["linkUrl"] = redisDb // sendData["pingLink"] = pingLink // sendData["err"] = err // sendData["redisErr"] = redisErr // sendData["redisCont"] = len(redisCont) var sendInfo RedisLinkState if err == nil { sendInfo.IsTrue = 1 } else { sendInfo.IsTrue = 2 publicmethod.Result(10001, sendInfo, c) return } if redisErr != nil { sendInfo.DbNumber = 16 } else { sendInfo.DbNumber = 16 if len(redisCont) == 2 { for k, v := range redisCont { fmt.Printf("%v: %v\n", k, v) // if k == 1 { // if val, isOk := v.(string); isOk { // sendInfo.DbNumber, _ = strconv.Atoi(val) // } // } } } } var redisListCont CountRedisKeyNumber for i := 0; i < sendInfo.DbNumber; i++ { syncSeting.Add(1) go redisListCont.TallyRedisKeys(redisConfig.Ip, redisConfig.Pwd, redisConfig.Port, i) } syncSeting.Wait() //根据维度序号排序 redisList := redisListCont.RedisList sort.Slice(redisList, func(i, j int) bool { return redisList[i].DbName < redisList[j].DbName }) sendInfo.RedisList = redisList // sendData["redisListCont"] = sendInfo // sendData["redisListContlen"] = len(sendInfo) publicmethod.Result(0, sendInfo, c) } /* * @ 作者: 秦东 @ 时间: 2023-11-14 10:19:13 @ 功能: 获取Redis有多少个数据库 @ 参数 # @ 返回值 # @ 方法原型 # */ func GainRedisDbNumber(redisDb *redis.Client) (dbNumber int) { redisRunDb := InitRedis(redisDb) redisCont, redisErr := redisRunDb.ConfigGet("databases") if redisErr != nil { dbNumber = 16 } else { dbNumber = 16 if len(redisCont) == 2 { for k, v := range redisCont { fmt.Printf("%v: %v\n", k, v) // if k == 1 { // if val, isOk := v.(string); isOk { // dbNumber, _ = strconv.Atoi(val) // } // } } } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-13 16:32:45 @ 功能: 计算Redis数据库键个数 @ 参数 #ip Redis数据库地址 #port 端口 #pwd 密码 #dbId 数据库值 @ 返回值 # @ 方法原型 # */ func (c *CountRedisKeyNumber) TallyRedisKeys(ip, pwd string, port, dbId int) { var redisDbConst RunOneRedis redisDbConst.Ip = ip redisDbConst.Port = port redisDbConst.Pwd = pwd redisDbConst.DbName = dbId redisDb := redisDbConst.OpenRedis() redisRunDb := InitRedis(redisDb) val, err := redisRunDb.Keys("*") // fmt.Printf("%v---->%v\n", dbId, val) if err == nil { var redisInfo RedisKeyNumber redisInfo.DbName = dbId redisInfo.DbNumber = len(val) c.RedisList = append(c.RedisList, redisInfo) } defer syncSeting.Done() } /* * @ 作者: 秦东 @ 时间: 2023-11-13 16:11:18 @ 功能: 打开Redis @ 参数 # @ 返回值 #156 6201 6190 @ 方法原型 # */ func (r *RunOneRedis) OpenRedis() (redisDb *redis.Client) { linkUrl := fmt.Sprintf("%v:%v", r.Ip, r.Port) redisDb = redis.NewClient(&redis.Options{ Addr: linkUrl, Password: r.Pwd, DB: r.DbName, }) return } /* * @ 作者: 秦东 @ 时间: 2023-11-14 08:04:08 @ 功能: 迁移数据库 @ 参数 # @ 返回值 # @ 方法原型 # */ func (a *ApiMethod) MoveOldRedisToNewRedis(c *gin.Context) { // var callBalackMsg MoveRedisMsg var requestData MoveRedis err := c.ShouldBindJSON(&requestData) if err != nil { publicmethod.Result(10001, err, c) return } if requestData.OriginRedis.State != 1 || requestData.TargetRedis.State != 1 { publicmethod.Result(10001, err, c, "请先测试源Redis与目标Redis是否链接成功!") return } if requestData.OriginRedis.Ip == "" || requestData.TargetRedis.Ip == "" { publicmethod.Result(10001, err, c, "请检查源RedisIP与目标RedisIP是否已填写!") return } if requestData.OriginRedis.Port == 0 { requestData.OriginRedis.Port = 6379 } if requestData.TargetRedis.Port == 0 { requestData.TargetRedis.Port = 6379 } // //源Redis链接 var redisDbOriginConst RunOneRedis redisDbOriginConst.Ip = requestData.OriginRedis.Ip redisDbOriginConst.Port = requestData.OriginRedis.Port redisDbOriginConst.Pwd = requestData.OriginRedis.Pwd redisDbOriginConst.DbName = 0 redisDbOrigin := redisDbOriginConst.OpenRedis() _, err = redisDbOrigin.Ping(context.Background()).Result() if err != nil { publicmethod.Result(10001, err, c, "源Redis链接失败!") return } // //目标Redis链接 // var redisDbTargetConst RunOneRedis // redisDbTargetConst.Ip = requestData.TargetRedis.Ip // redisDbTargetConst.Port = requestData.TargetRedis.Port // redisDbTargetConst.Pwd = requestData.TargetRedis.Pwd // redisDbTargetConst.DbName = 10 // redisDbTarget := redisDbTargetConst.OpenRedis() // _, err = redisDbTarget.Ping(context.Background()).Result() // if err != nil { // publicmethod.Result(10001, err, c, "目标Redis链接失败!") // return // } var redisMsg NewCopyOldRedisInfo if len(requestData.DbList) > 0 { for _, v := range requestData.DbList { syncSeting.Add(1) go redisMsg.NewsMoveOldRedis(requestData.OriginRedis, requestData.TargetRedis, v) } } else { dbNum := GainRedisDbNumber(redisDbOrigin) for i := 0; i < dbNum; i++ { syncSeting.Add(1) go redisMsg.NewsMoveOldRedis(requestData.OriginRedis, requestData.TargetRedis, i) } } syncSeting.Wait() redisList := redisMsg.MsgList sort.Slice(redisList, func(i, j int) bool { return redisList[i].DbName < redisList[j].DbName }) publicmethod.Result(0, redisList, c) } /* * @ 作者: 秦东 @ 时间: 2023-11-14 08:30:52 @ 功能: 数据迁移 @ 参数 # @ 返回值 # @ 方法原型 # */ func (n *NewCopyOldRedisInfo) NewsMoveOldRedis(oldRedis, newRedis RedisLink, dbName int) { // fmt.Printf("dbName--->%v\n", dbName) var msgCont MoveRedisMsg msgCont.DbName = dbName var redisDbOriginConst RunOneRedis redisDbOriginConst.Ip = oldRedis.Ip redisDbOriginConst.Port = oldRedis.Port redisDbOriginConst.Pwd = oldRedis.Pwd redisDbOriginConst.DbName = dbName redisDbOrigin := redisDbOriginConst.OpenRedis() _, err := redisDbOrigin.Ping(context.Background()).Result() if err == nil { //目标Redis链接 var redisDbTargetConst RunOneRedis redisDbTargetConst.Ip = newRedis.Ip redisDbTargetConst.Port = newRedis.Port redisDbTargetConst.Pwd = newRedis.Pwd redisDbTargetConst.DbName = dbName redisDbTarget := redisDbTargetConst.OpenRedis() _, err = redisDbTarget.Ping(context.Background()).Result() if err == nil { oldRunDb := InitRedis(redisDbOrigin) val, err := oldRunDb.Keys("*") if err != nil { var keyMsg MsgListInfo keyMsg.Keys = "源数据库" keyMsg.State = 2 keyMsg.Msg = err msgCont.MsgList = append(msgCont.MsgList, keyMsg) } else { if len(val) > 1 { newRunDb := InitRedis(redisDbTarget) for _, v := range val { var keyMsg MsgListInfo keyMsg.Keys = v vInfo, vErr := oldRunDb.KeyType(v) // fmt.Printf("%v: %v\n", v, vInfo) if vErr == nil { switch vInfo { case "string": //字符串 _, oldVal := oldRunDb.Get(v) oldTTl, _ := oldRunDb.TTl(v) if oldTTl < 0 { oldTTl = 0 } keyMsg.State = 1 newRunDb.SetRedisTime(oldTTl) newRunDb.Set(v, oldVal) keyMsg.Msg = "迁移完成!" // fmt.Printf("%v:-------------->1--->%v--->%v--->%v\n", v, oldTTl, oldTTl < 0, oldVal) case "list": //列表 oldVal, oldErr := oldRunDb.Lrange(v, 0, -1) if oldErr == nil { oldTTl, _ := oldRunDb.TTl(v) if oldTTl < 0 { oldTTl = 0 } newRunDb.SetRedisTime(oldTTl) for _, ov := range oldVal { newRunDb.Rpushx(v, ov) } keyMsg.Msg = "迁移完成!" keyMsg.State = 1 } else { keyMsg.Msg = oldErr keyMsg.State = 2 } // fmt.Printf("%v:-------------->2\n", v) case "set": //集合 oldVal, isTrue := oldRunDb.Smembers(v) if isTrue == nil { oldTTl, _ := oldRunDb.TTl(v) if oldTTl < 0 { oldTTl = 0 } newRunDb.SetRedisTime(oldTTl) newRunDb.Sadd(v, oldVal) keyMsg.Msg = "迁移完成!" keyMsg.State = 1 } else { keyMsg.Msg = "键不存在!" keyMsg.State = 2 } // fmt.Printf("%v:-------------->3\n", v) case "zset": //有序集 oldVal, isTrue := oldRunDb.Zrange(v, 0, -1) if isTrue == nil { oldTTl, _ := oldRunDb.TTl(v) if oldTTl < 0 { oldTTl = 0 } newRunDb.SetRedisTime(oldTTl) newRunDb.Zadd(v, oldVal) keyMsg.Msg = "迁移完成!" keyMsg.State = 1 } else { keyMsg.Msg = "键不存在!" keyMsg.State = 2 } // fmt.Printf("%v:-------------->4\n", v) case "hash": //哈希表 oldVal, isTrue := oldRunDb.HashGetAll(v) if isTrue { oldTTl, _ := oldRunDb.TTl(v) if oldTTl < 0 { oldTTl = 0 } newRunDb.SetRedisTime(oldTTl) newVal := publicmethod.MapOut[string]() for ni, nv := range oldVal { newVal[ni] = nv } newRunDb.HashMsetAdd(v, newVal) keyMsg.Msg = "迁移完成!" keyMsg.State = 1 } else { keyMsg.Msg = "键不存在!" keyMsg.State = 2 } // fmt.Printf("%v:-------------->5\n", v) default: keyMsg.Msg = "键不存在!" keyMsg.State = 2 // fmt.Printf("%v:-------------->6\n", v) } } else { keyMsg.Msg = vErr keyMsg.State = 2 } msgCont.MsgList = append(msgCont.MsgList, keyMsg) } } else { var keyMsg MsgListInfo keyMsg.Keys = "源数据库" keyMsg.Msg = "没有要迁移的数据!" keyMsg.State = 2 msgCont.MsgList = append(msgCont.MsgList, keyMsg) } } } else { var keyMsg MsgListInfo keyMsg.Keys = "目标数据库" keyMsg.Msg = err keyMsg.State = 2 msgCont.MsgList = append(msgCont.MsgList, keyMsg) } } else { var keyMsg MsgListInfo keyMsg.Keys = "源数据库" keyMsg.Msg = err keyMsg.State = 2 msgCont.MsgList = append(msgCont.MsgList, keyMsg) } n.MsgList = append(n.MsgList, msgCont) defer syncSeting.Done() }