You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
11 KiB
464 lines
11 KiB
package redisController
|
|
|
|
import (
|
|
"appPlatform/overall/publicmethod"
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-redis/redis/v8"
|
|
)
|
|
|
|
/*
|
|
*
|
|
@ 作者: 秦东
|
|
@ 时间: 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 {
|
|
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 {
|
|
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
|
|
@ 参数
|
|
|
|
#
|
|
|
|
@ 返回值
|
|
|
|
#
|
|
|
|
@ 方法原型
|
|
|
|
#
|
|
*/
|
|
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()
|
|
}
|
|
|