错误未知类型转到 [英] Error unknown type Go

查看:249
本文介绍了错误未知类型转到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Go非常陌生,只是在这里忍受着我。我试图编写一个代码,使用以下代码将mysql数据加载到redis集群: redis-go-群集
load2redis



这是代码。它有点长,只是在这里忍着。

 包主

导入(
字节
数据库/ sql
标志
//github.com/garyburd/redigo/redis
_github.com/go- sql-driver / mysql
//\"gopkg.in/redis.v4
github.com/chasex/redis-go-cluster
log
运行时
//字符串
同步
时间



var client * redis.Cluster

类型任务接口{
Execute()
}

类型池结构{
mu sync.Mutex

size int
任务chan任务
kill chan struct {}
wg sync.WaitGroup
}

func NewPool(size int)* Pool {
pool:=& Pool {
tasks:make(chan Task,128),
kill:make(chan struct {}),
}
pool.Resize大小)
返回池
}

func(p * Pool)worker(){
推迟p.wg.Done()
for {
选择{
case task,ok:=< -p.tasks:
if!ok {
return
}
task.Execute()
case< -p.kill:
return
}
}
}

func(p * Pool)Resize(n int){
p.mu.Lock()
推迟p.mu.Unlock()
为p.size< n {
p.size ++
p.wg.Add(1)
go p.worker()
}
for p.size> n {
p.size--
p.kill< - struct {} {}
}
}

func(p * Pool) Close(){
close(p.tasks)
}

func(p * Pool)Wait(){
p.wg.Wait()


$ func(p * Pool)Exec(任务任务){
p.tasks< - 任务
}

类型RedisTask struct {
索引int
命令字符串
键字符串
字符串
MapData map [字符串]字符串
}

func( e)RedisTask)Execute(){
log.Println(执行:,e.Key,,,e.Index)

如果e.Command ==SET{
_,err:= redis.String(client.Do(SET,e.Key,e.Value))
checkErr(err,set error:)
} else如果e.Command ==SADD{
_,err:= redis.Strings(client.Do(SADD,e.Key,e.Value))
checkErr(err,sadd错误:)
} else if e.Command ==HMSET{
_,err:= redis.StringMap(client.Do(HMSET,e.Key,e.MapData))
checkEr r(err,hmset error:)
}
// TODO:clean data
}

func main(){
runtime.GOMAXPROCS (runtime.NumCPU())
startTime:= time.Now()。UnixNano()/ int64(time.Millisecond)
host:= flag.String(s,localhost:3306 ,mysql server host and port,eg localhost:3306)
username:= flag.String(u,test,username to login mysql)
password:= flag.String (p,test,password for mysql)
database:= flag.String(d,test,要执行查询的数据库)
query:= flag.String(q,select 1;,your query sql)
ds:= flag.String(ds,key,redis structure)
PK: = flag.String(pk,Rkey,redis在mysql查询结果字段中的键值)

// redisHost:= flag.String(rs,localhost: 6379,redis主机和端口,例如localhost:6379)
// redisPassword:= flag.String(rp,test,redis password)

poolSize := flag.Int(size,10000,redis pool s ize)

flag.Parse()
var buf bytes.Buffer = bytes.Buffer {}
buf.WriteString(* username)
buf.WriteString( :)
buf.WriteString(* password)
buf.WriteString(@ tcp()
buf.WriteString(* host)
buf.WriteString() /)
buf.WriteString(* database)

db,err:= sql.Open(mysql,buf.String())
checkErr(err,连接到mysql错误!)
defer db.Close()

poolWorker:= NewPool(* poolSize)

//执行查询
行,err:= db.Query(* query)
checkErr(err,执行sql错误!)

// pool = newPool(* redisHost,* redisPassword,* poolSize)

// client = redis.NewClient(& redis.Options {
// Addr:* redisHost,
//密码:* redisPassword,//无密码设置
// DB:0,//使用默认的DB
//})

客户端,_ = redis.NewCluster(& redis.Options {
Sta rtNodes:[] string {10.xxx:6000,10.xxx:6001,10.xxx:6002},
ConnTimeout:50 * time.Millisecond,
ReadTimeout:50 * time.Millisecond,
WriteTimeout:50 * time.Millisecond,
KeepAlive:16,
AliveTime:60 * time.Second,
})
// checkErr (err,client error:)

// pong,err:= client.Ping()。Result()
// checkErr(err,redis client error:)
//log.Println(pong)

列,err:= rows.Columns()
checkErr(err,获取列错误!)

length:= len(列)
values:= make([] sql.RawBytes,length)

scanArgs:= make([] interface {},len(values) )
for i:=范围值{
scanArgs [i] =& values [i]
}

count:= 0
for rows .Next(){
count + = 1
err = rows.Scan(scanArgs ...)
checkErr(err,scan error)

var VA lue string
var key string

var任务RedisTask

if * ds ==key{
key = getStringData(values [0])
value = getStringData(values [1])$ ​​b $ b if value!={
task = RedisTask {
索引:count,
命令:SET,
Key:key,
Value:value,
}
}
} else if * ds ==set{
key = getStringData(values [b]
value = getStringData(values [1])$ ​​b $ b if value!={
task = RedisTask {
Index:count,
Command: SADD,
Key:key,
Value:value,
}
}
} else if * ds ==hash{
key = getStringData(values [0])
添加(键)
$ bm:= make(map [string]字符串)

for i,col:=范围值{/ / args:= redis.Args {}。
如果col!= nil&&列[i]!= * PK {
value = getStringData(col)
m [columns [i]] = value
}
}
task = RedisTask {
索引:count,
命令:HMSET,
键:键,
MapData:m,
}
}
poolWorker.Exec (任务)
}
if err = rows.Err(); err!= nil {
panic(err.Error())//正确的错误处理,而不是应用程序中的恐慌
}

poolWorker.Close()

poolWorker.Wait()

EndTime:= time.Now()。UnixNano()/ int64(time.Millisecond)
log.Println(===== ===================================执行时间:,EndTime-startTimems,总数: ,count)
}

func getStringData(data sql.RawBytes)string {
if data == nil {
return
}
value:string(data)
return clearBad(value)
}

func clearBad(str string)string {
// str = strings.Trim (str,`)
// str = strings.Trim(str,½€)
// str = strings.Trim(str, - )
// str = strings.Trim(str,。)
// str = strings.Trim(str,)
// str = strings.Trim(str,;)
// str = strings.Trim(str,,)
// str = strings.Trim(str,:)
// str = strings.Trim(str,; )
// str = strings.Trim(str,')
// str = strings.Trim(str,!)
return str
}

func checkErr(err error,msg string){
if err!= nil {
log.Fatalln(msg,err)
}
}


<$ p $选择CONCAT('student:',c.sid)Rkey,c.sname SNAME,c .saddress SADDRESS,c.sage SAGE FROM STUDENT c WHERE c.sid> 0;-ds hash -size 1200
2017/07/21 10:29:09 rak.go:93:执行:student:2,2
2017/07/21 10:29:09 rak.go:93:正在执行:学生:1,
2017/07/21 10:29:09 rak.go:93:正在执行:学生:3,3
2017/07/21 10 :29:09 rak.go:268:hmset错误:Do:unknown type map [string] string
$

有人可以向我解释我在这里做错了什么吗?我会非常感激。

解决方案

正如所指出的, Do 不适用于地图,这是您可以修复它的一种方式。



<$ p $如果e.Command ==HMSET{
//建立一个字符串片来保存键值对
args:= make([] string, 0,len(e.MapData)* 2)
for k,v:= range e.MapData {
args = append(args,k,v)
}
_ ,err:= redis.StringMap(client.Do(HMSET,e.Key,args ...))
checkErr(err,hmset error:)
}

Do方法映射到预计Redis命令集和参数的方式相同。例如。

  127.0.0.1:6379> HMSET myKey foo bar baz boff 
OK
127.0.0.1:6379> HGETALL myKey
1)foo
2)bar
3)baz
4)boff
127.0.0.1:6379>

在您的代码中使用redis客户端的相同映射集操作将是

  client.Do(HMSET,myKey,foo,bar,baz,boff)

当地图的键和值的参数是动态的时,最简单的方法是

  client.Do(HMSET,myKey,[] string {foo,bar,baz,boff} ...)

这正是上面第一个代码块的功能。


i'm really new to Go, su just bear with me here. I'm trying to write a code for loading mysql data to redis cluster using following :redis-go-cluster, load2redis

This is the code. Its a little bit long, just bear with me here.

package main

import (
    "bytes"
    "database/sql"
    "flag"
    // "github.com/garyburd/redigo/redis"
    _ "github.com/go-sql-driver/mysql"
    //"gopkg.in/redis.v4"
    "github.com/chasex/redis-go-cluster"
    "log"
    "runtime"
    // "strings"
    "sync"
    "time"

)

var client *redis.Cluster

type Task interface {
    Execute()
}

type Pool struct {
    mu sync.Mutex

    size  int
    tasks chan Task
    kill  chan struct{}
    wg    sync.WaitGroup
}

func NewPool(size int) *Pool {
    pool := &Pool{
        tasks: make(chan Task, 128),
        kill:  make(chan struct{}),
    }
    pool.Resize(size)
    return pool
}

func (p *Pool) worker() {
    defer p.wg.Done()
    for {
        select {
        case task, ok := <-p.tasks:
            if !ok {
                return
            }
            task.Execute()
        case <-p.kill:
            return
        }
    }
}

func (p *Pool) Resize(n int) {
    p.mu.Lock()
    defer p.mu.Unlock()
    for p.size < n {
        p.size++
        p.wg.Add(1)
        go p.worker()
    }
    for p.size > n {
        p.size--
        p.kill <- struct{}{}
    }
}

func (p *Pool) Close() {
    close(p.tasks)
}

func (p *Pool) Wait() {
    p.wg.Wait()
}

func (p *Pool) Exec(task Task) {
    p.tasks <- task
}

type RedisTask struct {
    Index   int
    Command string
    Key     string
    Value   string
    MapData map[string]string
}

func (e RedisTask) Execute() {
    log.Println("executing:", e.Key, ",", e.Index)

    if e.Command == "SET" {
        _,err := redis.String(client.Do("SET", e.Key, e.Value))
        checkErr(err, "set error:")
    } else if e.Command == "SADD" {
        _,err := redis.Strings(client.Do("SADD", e.Key, e.Value))
        checkErr(err, "sadd error:") 
    } else if e.Command == "HMSET" {
        _,err := redis.StringMap(client.Do("HMSET", e.Key, e.MapData))
        checkErr(err, "hmset error:")
    }
    // TODO: clean data
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    startTime := time.Now().UnixNano() / int64(time.Millisecond)
    host := flag.String("s", "localhost:3306", "mysql server host and port ,eg localhost:3306")
    username := flag.String("u", "test", "username to login mysql")
    password := flag.String("p", "test", "password for mysql")
    database := flag.String("d", "test", "database you want to execute query")
    query := flag.String("q", "select 1;", "your query sql")
    ds := flag.String("ds", "key", "redis structure")
    PK := flag.String("pk", "Rkey", "the redis Key in the fields of mysql query result")

    //redisHost := flag.String("rs", "localhost:6379", "redis host and port ,eg localhost:6379")
    //redisPassword := flag.String("rp", "test", "redis password")

    poolSize := flag.Int("size", 10000, "redis pool size")

    flag.Parse()
    var buf bytes.Buffer = bytes.Buffer{}
    buf.WriteString(*username)
    buf.WriteString(":")
    buf.WriteString(*password)
    buf.WriteString("@tcp(")
    buf.WriteString(*host)
    buf.WriteString(")/")
    buf.WriteString(*database)

    db, err := sql.Open("mysql", buf.String())
    checkErr(err, "connect to mysql error !")
    defer db.Close()

    poolWorker := NewPool(*poolSize)

    // Execute the query
    rows, err := db.Query(*query)
    checkErr(err, "execute sql error!")

    // pool = newPool(*redisHost, *redisPassword, *poolSize)

    //client = redis.NewClient(&redis.Options{
    //  Addr:     *redisHost,
    //  Password: *redisPassword, // no password set
    //  DB:       0,              // use default DB
    //})

    client,_ = redis.NewCluster(&redis.Options{
            StartNodes: []string{"10.x.x.x:6000", "10.x.x.x:6001", "10.x.x.x:6002"},
            ConnTimeout: 50 * time.Millisecond,
            ReadTimeout: 50 * time.Millisecond,
            WriteTimeout: 50 * time.Millisecond,
            KeepAlive: 16,
            AliveTime: 60 * time.Second,
    })
    //checkErr(err, "client error:")

    //pong, err := client.Ping().Result()
    //checkErr(err, "redis client error:")
    //log.Println(pong)

    columns, err := rows.Columns()
    checkErr(err, "get columns error!")

    length := len(columns)
    values := make([]sql.RawBytes, length)

    scanArgs := make([]interface{}, len(values))
    for i := range values {
        scanArgs[i] = &values[i]
    }

    count := 0
    for rows.Next() {
        count += 1
        err = rows.Scan(scanArgs...)
        checkErr(err, "scan error")

        var value string
        var key string

        var task RedisTask

        if *ds == "key" {
            key = getStringData(values[0])
            value = getStringData(values[1])
            if value != "" {
                task = RedisTask{
                    Index:   count,
                    Command: "SET",
                    Key:     key,
                    Value:   value,
                }
            }
        } else if *ds == "set" {
            key = getStringData(values[0])
            value = getStringData(values[1])
            if value != "" {
                task = RedisTask{
                    Index:   count,
                    Command: "SADD",
                    Key:     key,
                    Value:   value,
                }
            }
        } else if *ds == "hash" {
            key = getStringData(values[0])
            // args := redis.Args{}.Add(key)

            m := make(map[string]string)

            for i, col := range values {
                if col != nil && columns[i] != *PK {
                    value = getStringData(col)
                    m[columns[i]] = value
                }
            }
            task = RedisTask{
                Index:   count,
                Command: "HMSET",
                Key:     key,
                MapData: m,
            }
        }
        poolWorker.Exec(task)
    }
    if err = rows.Err(); err != nil {
        panic(err.Error()) // proper error handling instead of panic in your app
    }

    poolWorker.Close()

    poolWorker.Wait()

    EndTime := time.Now().UnixNano() / int64(time.Millisecond)
    log.Println("======================================== executing time:", EndTime-startTime, " ms, total:", count)
}

func getStringData(data sql.RawBytes) string {
    if data == nil {
        return ""
    }
    value := string(data)
    return clearBad(value)
}

func clearBad(str string) string {
    // str = strings.Trim(str, "`")
    // str = strings.Trim(str, "ï½€")
    // str = strings.Trim(str, "-")
    // str = strings.Trim(str, ".")
    // str = strings.Trim(str, " ")
    // str = strings.Trim(str, ";")
    // str = strings.Trim(str, ",")
    // str = strings.Trim(str, ":")
    // str = strings.Trim(str, ";")
    // str = strings.Trim(str, "'")
    // str = strings.Trim(str, "!")
    return str
}

func checkErr(err error, msg string) {
    if err != nil {
        log.Fatalln(msg, err)
    }
}

When i'm executing it, i'm getting following exception:

./rak -u user -p user -s 10.X.X.X:8080 -d test -q "SELECT CONCAT( 'student:', c.sid ) Rkey, c.sname SNAME, c.saddress SADDRESS, c.sage SAGE FROM STUDENT c WHERE c.sid  > 0;" -ds hash -size 1200
2017/07/21 10:29:09 rak.go:93: executing: student:2 , 2
2017/07/21 10:29:09 rak.go:93: executing: student:1 , 1
2017/07/21 10:29:09 rak.go:93: executing: student:3 , 3
2017/07/21 10:29:09 rak.go:268: hmset error: Do: unknown type map[string]string
$

Can somebody explain to me what i'm doing wrong here? I'd be very grateful.

解决方案

As pointed out, Do does not work with maps. This is one way you could fix it.

} else if e.Command == "HMSET" {
    // Build up a string slice to hold the key value pairs
    args := make([]string, 0, len(e.MapData) * 2)
    for k, v := range e.MapData {
        args = append(args, k, v)
    }
    _,err := redis.StringMap(client.Do("HMSET", e.Key, args...))
    checkErr(err, "hmset error:")
}

The Do method maps to the Redis command set and arguments are expected in the same way. For example.

127.0.0.1:6379> HMSET myKey foo bar baz boff
OK
127.0.0.1:6379> HGETALL myKey
1) "foo"
2) "bar"
3) "baz"
4) "boff"
127.0.0.1:6379>

The same map-set operation using the redis client in your code would be

client.Do("HMSET", "myKey", "foo", "bar", "baz", "boff")

When the arguments for keys and values of the map are dynamic, the most straight forward way is

client.Do("HMSET", "myKey", []string{"foo", "bar", "baz", "boff"}...)

which is exactly what the first code block above does.

这篇关于错误未知类型转到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆