当前位置:   article > 正文

Go实战--golang中使用redis(redigo和go-redis/redis这个已测试)_golang redis 压力测试 代码

golang redis 压力测试 代码

自己做测试了没有问题,虚拟机连不上可以把包下载到本地。

生命不止,继续 go go go !!!

以前介绍过golang中如何使用sqlite3: 
Go实战–go语言操作sqlite数据库(The way to go)

今天跟大家分享的是如何在golang中使用redis数据库。

何为redis

官网: 
https://redis.io/

Redis is an in-memory database open-source software project implementing a networked, in-memory key-value store with optional durability. 
Redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。

Redis 优势 
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis与其他key-value存储有什么不同? 
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

windows安装redis

这里只简单介绍一下Windows上redis的安装: 
在官网中可以看到这样的描述: 
Windows 
The Redis project does not officially support Windows. However, the Microsoft Open Tech group develops and maintains this Windows port targeting Win64

下载 
直接去github上下载就好了: 
https://github.com/MicrosoftArchive/redis/releases

这里可以下载msi文件和zip文件,两者区别就是msi文件是安装文件,安装的过程中会帮助我们配好环境变量,所以推荐。

这里需要提示一下安装过程中,如果修改了端口号,一定要记住: 
图1

启动服务端 
安装成功后,通过终端键入如下命令:

redis-server.exe redis.windows.conf
  • 1
  • 1

一切没问题会出现下面的提示: 
[11368] 13 Jul 10:10:31.487 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error

启动客户端 
新打开一个终端,启动redis客户端,键入命令:

redis-cli.exe -h 127.0.0.1 -p 6379
  • 1
  • 1

测试:

  1. 127.0.0.1:6379> set mykey abc
  2. OK
  3. 127.0.0.1:6379> get mykey
  4. "abc"
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

开源库redigo的使用

github地址: 
https://github.com/garyburd/redigo

文档地址: 
http://godoc.org/github.com/garyburd/redigo/redis

获取:

go get github.com/garyburd/redigo/redis
  • 1
  • 1

连接redis

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. fmt.Println("Connect to redis error", err)
  10. return
  11. }
  12. defer c.Close()
  13. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

读写 
这里写入的值永远不会过期

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. fmt.Println("Connect to redis error", err)
  10. return
  11. }
  12. defer c.Close()
  13. _, err = c.Do("SET", "mykey", "superWang")
  14. if err != nil {
  15. fmt.Println("redis set failed:", err)
  16. }
  17. username, err := redis.String(c.Do("GET", "mykey"))
  18. if err != nil {
  19. fmt.Println("redis get failed:", err)
  20. } else {
  21. fmt.Printf("Get mykey: %v \n", username)
  22. }
  23. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

如何设置过期呢,可以使用SET的附加参数:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/garyburd/redigo/redis"
  6. )
  7. func main() {
  8. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  9. if err != nil {
  10. fmt.Println("Connect to redis error", err)
  11. return
  12. }
  13. defer c.Close()
  14. _, err = c.Do("SET", "mykey", "superWang", "EX", "5")
  15. if err != nil {
  16. fmt.Println("redis set failed:", err)
  17. }
  18. username, err := redis.String(c.Do("GET", "mykey"))
  19. if err != nil {
  20. fmt.Println("redis get failed:", err)
  21. } else {
  22. fmt.Printf("Get mykey: %v \n", username)
  23. }
  24. time.Sleep(8 * time.Second)
  25. username, err = redis.String(c.Do("GET", "mykey"))
  26. if err != nil {
  27. fmt.Println("redis get failed:", err)
  28. } else {
  29. fmt.Printf("Get mykey: %v \n", username)
  30. }
  31. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

输出: 
Get mykey: superWang 
redis get failed: redigo: nil returned

批量写入读取

MGET key [key …] 
MSET key value [key value …]

批量写入读取对象(Hashtable) 
HMSET key field value [field value …] 
HMGET key field [field …]

检测值是否存在 
EXISTS key

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. fmt.Println("Connect to redis error", err)
  10. return
  11. }
  12. defer c.Close()
  13. _, err = c.Do("SET", "mykey", "superWang")
  14. if err != nil {
  15. fmt.Println("redis set failed:", err)
  16. }
  17. is_key_exit, err := redis.Bool(c.Do("EXISTS", "mykey1"))
  18. if err != nil {
  19. fmt.Println("error:", err)
  20. } else {
  21. fmt.Printf("exists or not: %v \n", is_key_exit)
  22. }
  23. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

输出: 
exists or not: false

删除 
DEL key [key …]

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. fmt.Println("Connect to redis error", err)
  10. return
  11. }
  12. defer c.Close()
  13. _, err = c.Do("SET", "mykey", "superWang")
  14. if err != nil {
  15. fmt.Println("redis set failed:", err)
  16. }
  17. username, err := redis.String(c.Do("GET", "mykey"))
  18. if err != nil {
  19. fmt.Println("redis get failed:", err)
  20. } else {
  21. fmt.Printf("Get mykey: %v \n", username)
  22. }
  23. _, err = c.Do("DEL", "mykey")
  24. if err != nil {
  25. fmt.Println("redis delelte failed:", err)
  26. }
  27. username, err = redis.String(c.Do("GET", "mykey"))
  28. if err != nil {
  29. fmt.Println("redis get failed:", err)
  30. } else {
  31. fmt.Printf("Get mykey: %v \n", username)
  32. }
  33. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

输出: 
Get mykey: superWang 
redis get failed: redigo: nil returned

读写json到redis

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/garyburd/redigo/redis"
  6. )
  7. func main() {
  8. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  9. if err != nil {
  10. fmt.Println("Connect to redis error", err)
  11. return
  12. }
  13. defer c.Close()
  14. key := "profile"
  15. imap := map[string]string{"username": "666", "phonenumber": "888"}
  16. value, _ := json.Marshal(imap)
  17. n, err := c.Do("SETNX", key, value)
  18. if err != nil {
  19. fmt.Println(err)
  20. }
  21. if n == int64(1) {
  22. fmt.Println("success")
  23. }
  24. var imapGet map[string]string
  25. valueGet, err := redis.Bytes(c.Do("GET", key))
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. errShal := json.Unmarshal(valueGet, &imapGet)
  30. if errShal != nil {
  31. fmt.Println(err)
  32. }
  33. fmt.Println(imapGet["username"])
  34. fmt.Println(imapGet["phonenumber"])
  35. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

设置过期时间 
EXPIRE key seconds

  1. // 设置过期时间为24小时
  2. n, _ := rs.Do("EXPIRE", key, 24*3600)
  3. if n == int64(1) {
  4. fmt.Println("success")
  5. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

列表操作 
命令:

  1. redis 127.0.0.1:6379> LPUSH runoobkey redis
  2. (integer) 1
  3. redis 127.0.0.1:6379> LPUSH runoobkey mongodb
  4. (integer) 2
  5. redis 127.0.0.1:6379> LPUSH runoobkey mysql
  6. (integer) 3
  7. redis 127.0.0.1:6379> LRANGE runoobkey 0 10
  8. 1) "mysql"
  9. 2) "mongodb"
  10. 3) "redis"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

代码实现:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. c, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. fmt.Println("Connect to redis error", err)
  10. return
  11. }
  12. defer c.Close()
  13. _, err = c.Do("lpush", "runoobkey", "redis")
  14. if err != nil {
  15. fmt.Println("redis set failed:", err)
  16. }
  17. _, err = c.Do("lpush", "runoobkey", "mongodb")
  18. if err != nil {
  19. fmt.Println("redis set failed:", err)
  20. }
  21. _, err = c.Do("lpush", "runoobkey", "mysql")
  22. if err != nil {
  23. fmt.Println("redis set failed:", err)
  24. }
  25. values, _ := redis.Values(c.Do("lrange", "runoobkey", "0", "100"))
  26. for _, v := range values {
  27. fmt.Println(string(v.([]byte)))
  28. }
  29. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

输出: 
mysql 
mongodb 
redis

管道

请求/响应服务可以实现持续处理新请求,即使客户端没有准备好读取旧响应。这样客户端可以发送多个命令到服务器而无需等待响应,最后在一次读取多个响应。这就是管道化(pipelining),这个技术在多年就被广泛使用了。距离,很多POP3协议实现已经支持此特性,显著加速了从服务器下载新邮件的过程。 
Redis很早就支持管道化,所以无论你使用任何版本,你都可以使用管道化技术

连接支持使用Send(),Flush(),Receive()方法支持管道化操作

  1. Send(commandName string, args ...interface{}) error
  2. Flush() error
  3. Receive() (reply interface{}, err error)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

Send向连接的输出缓冲中写入命令。Flush将连接的输出缓冲清空并写入服务器端。Recevie按照FIFO顺序依次读取服务器的响应。下例展示了一个简单的管道:

  1. c.Send("SET", "foo", "bar")
  2. c.Send("GET", "foo")
  3. c.Flush()
  4. c.Receive() // reply from SET
  5. v, err = c.Receive() // reply from GET
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

Do方法组合了Send,Flush和 Receive方法。Do方法先写入命令,然后清空输出buffer,最后接收全部挂起响应包括Do方发出的命令的结果。如果任何响应中包含一个错误,Do返回错误。如果没有错误,Do方法返回最后一个响应。

开源库go-redis/redis的使用

github地址: 
https://github.com/go-redis/redis

文档地址: 
https://godoc.org/github.com/go-redis/redis

获取:

go get -u github.com/go-redis/redis
  • 1
  • 1

应用:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/go-redis/redis"
  5. )
  6. func main() {
  7. client := redis.NewClient(&redis.Options{
  8. Addr: "127.0.0.1:6379",
  9. Password: "", // no password set
  10. DB: 0, // use default DB
  11. })
  12. pong, err := client.Ping().Result()
  13. fmt.Println(pong, err)
  14. err = client.Set("key", "value", 0).Err()
  15. if err != nil {
  16. panic(err)
  17. }
  18. val, err := client.Get("key").Result()
  19. if err != nil {
  20. panic(err)
  21. }
  22. fmt.Println("key", val)
  23. val2, err := client.Get("key2").Result()
  24. if err == redis.Nil {
  25. fmt.Println("key2 does not exists")
  26. } else if err != nil {
  27. panic(err)
  28. } else {
  29. fmt.Println("key2", val2)
  30. }
  31. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

输出: 
PONG 
key value 
key2 does not exists

这里写图片描述

 

来源:http://blog.csdn.net/wangshubo1989/article/details/75050024

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/723912
推荐阅读
相关标签
  

闽ICP备14008679号