redis与go

参考资料

redis实战 http://redisinaction.com/index.html

redis中文网 http://redis.net.cn/

goredis地址:https://github.com/gomodule/redigo


Redis拥有其他数据库所不具备的数据结构,是内存数据库(这使得Redis的速度非常快),具有远程(这使得Redis可以连接多个客户端和服务器)、持久化(这使得服务器可以在重启之后仍然保持重启之前的数据)和可扩展(通过主从复制和分片)等多个特性,使得用户可以以熟悉的方式来为各种不同的问题构建解决方案。

使用场景

1、配合关系型数据库做高速缓存。

例如:高频词、热点访问的数据,降低数据库IO;分布式架构,做session共享。

2、利用多样的数据类型,存储特定的数据。

例如:最新N个数据——通过list实现按自然时间排序的数据。

           排行榜,top N——利用zset(有序集合)

           时效性的数据,如手机验证码——expire过期

扫描二维码关注公众号,回复: 6085136 查看本文章

           计数器,秒杀——原子性,自增方法INCR、DECR

           去除大量数据中的重复数据——利用set集合

           构建队列——利用list集合

           发布订阅消息系统——pub/sub模式

5种数据结构类型

1、STRING(字符串) :包括字节串(byte string),整数,浮点数

GET 获取存储在给定键中的值
SET 设置存储在给定键中的值
DEL 删除存储在给定键中的值(这个命令可以用于所有类型)

Redis中的自增命令和自减命令

INCR INCR key-name——将键存储的值加上1
DECR DECR key-name——将键存储的值减去1
INCRBY INCRBY key-name amount——将键存储的值加上整数amount
DECRBY DECRBY key-name amount——将键存储的值减去整数amount
INCRBYFLOAT INCRBYFLOAT key-name amount——将键存储的值加上浮点数amount,这个命令在Redis 2.6或以上的版本可用

 供Redis处理子串和二进制位的命令

APPEND APPEND key-name value——将提供的值value追加到给定键key-name当前存储的值的末尾
GETRANGE GETRANGE key-name start end——获取一个由偏移量start至偏移量end范围内所有字符组成的子串,包括startend在内
SETRANGE SETRANGE key-name offset value——将从start偏移量开始的子串设置为给定value
GETBIT GETBIT key-name offset——将字节串看作是二进制位串(bit string),并返回位串中偏移量为offset的二进制位的值
SETBIT SETBIT key-name offset value——将字节串看作是二进制位串,并将位串中偏移量为offset的二进制位的值设置为value
BITCOUNT BITCOUNT key-name [start end]——统计二进制位串里面值为1的二进制位的数量,如果给定了可选的start偏移量和end偏移量,那么只对偏移量指定范围内的二进制位进行统计
BITOP BITOP operation dest-key key-name [key-name ...]——对一个或多个二进制位串执行包括并(AND)、或(OR)、异或(XOR)、 非(NOT)在内的任意一种按位运算操作(bitwise operation),并将计算得出的结果保存在dest-key键里面

2、LIST(列表)

RPUSH RPUSH key-name value [value ...]——将一个或多个值推入到列表的右端
LPUSH LPUSH key-name value [value ...]——将一个或多个值推入到列表的左端
RPOP RPOP key-name——移除并返回列表最右端的元素
LPOP LPOP key-name——移除并返回列表最左端的元素
LINDEX LINDEX key-name offset——返回列表中偏移量为offset的元素
LRANGE LRANGE key-name start end——返回列表从start偏移量到end偏移量范围内的所有元素,包括startend
LTRIM LTRIM key-name start end——对列表进行修剪,只保留从start偏移量到end偏移量范围内的元素,包括startend

阻塞式的列表弹出命令以及在列表之间移动元素的命令

BLPOP BLPOP key-name [key-name ...] timeout——从第一个非空列表中弹出位于最左端的元素,或者在timeout秒之内阻塞并等待可弹出的元素出现
BRPOP BRPOP key-name [key-name ...] timeout——从第一个非空列表中弹出位于最右端的元素,或者在timeout秒之内阻塞并等待可弹出的元素出现
RPOPLPUSH RPOPLPUSH source-key dest-key——从source-key列表中弹出位于最右端的元素,然后将这个元素推入到dest-key列表的最左端,并向用户返回这个元素
BRPOPLPUSH BRPOPLPUSH source-key dest-key timeout——从source-key列表中弹出位于最右端的元素,然后将这个元素推入到dest-key列表的最左端, 并向用户返回这个元素;如果source-key为空,那么在timeout秒之内阻塞并等待可弹出的元素出现

3、SET(集合)

SADD SADD key-name item [item ...]——将一个或多个元素添加到集合里面,并返回被添加元素当中原本并不存在于集合里面的元素数量
SREM SREM key-name item [item ...]——从集合里面移除一个或多个元素,并返回被移除元素的数量
SISMEMBER SISMEMBER key-name item——检查元素item是否存在于集合key-name
SCARD SCARD key-name——返回集合包含的元素的数量
SMEMBERS SMEMBERS key-name——返回集合包含的所有元素
SRANDMEMBER SRANDMEMBER key-name [count]——从集合里面随机地返回一个或多个元素。当count为正数时,命令返回的随机元素不会重复; 当count为负数时,命令返回的随机元素可能会出现重复
SPOP SPOP key-name——从集合里面移除并返回一个随机元素
SMOVE SMOVE source-key dest-key item——如果集合source-key包含元素item, 那么从集合source-key里面移除元素item,并将元素item添加到集合dest-key中; 如果item被成功移除,那么命令返回1,否则返回0

用于组合和处理多个集合的Redis命令

SDIFF SDIFF key-name [key-name ...]——返回那些存在于第一个集合、但不存在于其他集合中的元素(数学上的差集运算)
SDIFFSTORE SDIFFSTORE dest-key key-name [key-name ...]——将那些存在于第一个集合、但并不存在于其他集合中的元素(数学上的差集运算)存储到dest-key
SINTER SINTER key-name [key-name ...]——返回那些同时存在于所有集合中的元素(数学上的交集运算)
SINTERSTORE SINTERSTORE dest-key key-name [key-name ...]——将那些同时存在于所有集合的元素(数学上的交集运算)保存到键dest-key
SUNION SUNION key-name [key-name ...]——返回那些至少存在于一个集合中的元素(数学上的并集计算)
SUNIONSTORE SUNIONSTORE dest-key key-name [key-name ...]——将那些至少存在于一个集合中的元素(数学上的并集计算)存储到dest-key

4、HASH(散列)

HSET 在散列里面关联起给定的键值对
HGET 获取指定散列键的值
HMGET HMGET key-name key [key ...]——从散列里面获取一个或多个键的值
HMSET HMSET key-name key value [key value ...]——为散列里面的一个或多个键设置值
HDEL HDEL key-name key [key ...]——删除散列里面的一个或多个键值对,返回成功找到并删除的键值对数量
HLEN HLEN key-name——返回散列包含的键值对数量
HEXISTS HEXISTS key-name key——检查给定键是否存在于散列中
HKEYS HKEYS key-name——获取散列包含的所有键
HVALS HVALS key-name——获取散列包含的所有值
HGETALL HGETALL key-name——获取散列包含的所有键值对
HINCRBY HINCRBY key-name key increment——将键key保存的值加上整数increment
HINCRBYFLOAT HINCRBYFLOAT key-name key increment——将键key保存的值加上浮点数increment

5、ZSET(有序集合)

ZADD ZADD key-name score member [score member ...]——将带有给定分值的成员添加到有序集合里面
ZREM ZREM key-name member [member ...]——从有序集合里面移除给定的成员,并返回被移除成员的数量
ZCARD ZCARD key-name——返回有序集合包含的成员数量
ZINCRBY ZINCRBY key-name increment member——将member成员的分值加上increment
ZCOUNT ZCOUNT key-name min max——返回分值介于minmax之间的成员数量
ZRANK ZRANK key-name member——返回成员memberkey-name中的排名
ZSCORE ZSCORE key-name member——返回成员member的分值
ZRANGE ZRANGE key-name start stop [WITHSCORES]——返回有序集合中排名介于startstop之间的成员,如果给定了可选的WITHSCORES选项,那么命令会将成员的分值也一并返回

有序集合的范围型数据获取命令和范围型数据删除命令,以及并集命令和交集命令

ZREVRANK ZREVRANK key-name member——返回有序集合里成员member所处的位置,成员按照分值从大到小排列
ZREVRANGE ZREVRANGE key-name start stop [WITHSCORES]——返回有序集合给定排名范围内的成员,成员按照分值从大到小排列
ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]——返回有序集合中,分值介于minmax之间的所有成员
ZREVRANGEBYSCORE ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]——获取有序集合中分值介于minmax之间的所有成员,并按照分值从大到小的顺序来返回它们
ZREMRANGEBYRANK ZREMRANGEBYRANK key-name start stop——移除有序集合中排名介于startstop之间的所有成员
ZREMRANGEBYSCORE ZREMRANGEBYSCORE key-name min max——移除有序集合中分值介于minmax之间的所有成员
ZINTERSTORE ZINTERSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]——对给定的有序集合执行类似于集合的交集运算
ZUNIONSTORE ZUNIONSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]——对给定的有序集合执行类似于集合的并集运算

发布与订阅模式

命令 用例和描述
SUBSCRIBE SUBSCRIBE channel [channel ...]——订阅给定的一个或多个频道
UNSUBSCRIBE UNSUBSCRIBE [channel [channel ...]]——退订给定的一个或多个频道,如果执行时没有给定任何频道,那么退订所有频道
PUBLISH PUBLISH channel message——向给定频道发送消息
PSUBSCRIBE PSUBSCRIBE pattern [pattern ...]——订阅与给定模式相匹配的所有频道
PUNSUBSCRIBE PUNSUBSCRIBE [pattern [pattern ...]]——退订给定的模式,如果执行时没有给定任何模式,那么退订所有模式

SORT命令

使用SORT命令提供的选项可以实现以下功能:根据降序而不是默认的升序来排序元素;将元素看作是数字来进行排序,或者将元素看作是二进制字符串来进行排序(比如排序字符串'110''12'的结果就跟排序数字11012的结果不一样);使用被排序元素之外的其他值作为权重来进行排序,甚至从输入的列表、集合或者有序集合那里获取外部值等等。

//如果不加STORE list1,则返回一个排序后的列表,list1不改变。也可储存到其他列表名中
re,err = conn.Do("SORT","list1","STORE","list1")
	errCheck(err)
	fmt.Println(re) //返回列表长度

事务

Redis是单线程队列式地执行所有客户端发过来的命令,Redis的基本事务(basic transaction)使用MULTI命令和EXEC命令,让一个客户端在不被其他客户端打断的情况下执行多个命令。和关系数据库那种可以在执行的过程中进行回滚(rollback)的事务不同,在Redis里面,被MULTI命令和EXEC命令包围的所有命令会作为一个整体按顺序执行。当一个事务执行完毕之后,Redis才会处理其他客户端的命令。

REDIS事务分组队阶段和执行阶段,MULTI命令和EXEC命令之间是组队阶段,EXEC命令之后是执行阶段。一个事务不具有原子性,即如果一个事务组队完毕,在执行阶段出错,不会整体回滚,错误命令前后的正确的命令会执行。在组队阶段出错,EXEC命令之前如果命令出现错误,事务整体失效,且再执行EXEC命令会报错。

组队过程中,可通过DISCARD命令撤销组队,且事务中所有命令失效,再执行EXEC命令会报错。

用户在事务前使用WATCH key [key...]命令对键进行监视之后,直到执行EXEC命令的这段时间里,如果有其他客户端抢先对任何被监视的键进行了替换、更新删除等操作(及时新值与旧值相等),该用户在尝试执行EXEC命令时,事务将失败并返回错误。UNWATCH命令取消所有监控。如果事务成功执行,在执行EXEC命令时会自动取消所有监控。

键的过期操作

PERSIST PERSIST key-name——移除键的过期时间
TTL TTL key-name——返回给定键距离过期还有多少秒
EXPIRE EXPIRE key-name seconds——让键key-name在给定的seconds秒之后过期
EXPIREAT EXPIREAT key-name timestamp——将给定键的过期时间设置为给定的UNIX时间戳
PTTL PTTL key-name——返回给定键距离过期时间还有多少毫秒,这个命令在Redis 2.6或以上版本可用
PEXPIRE PEXPIRE key-name milliseconds——让键key-namemilliseconds毫秒之后过期,这个命令在Redis 2.6或以上版本可用
PEXPIREAT PEXPIREAT key-name timestamp-milliseconds——将一个毫秒级精度的UNIX时间戳设置为给定键的过期时间,这个命令在Redis 2.6或以上版本可用

REDIS持久化

两种方法:RDB(redis database)、AOF(append of file)

两个方法同时启用的话,系统默认采用AOF文件,此时RDB文件可以辅助判断AOF文件是否有误。

用哪个好:1、官方推荐两个都启用;2、如果对数据不敏感,可以单独用RDB;3、不建议单独用AOF,因为可能会出现BUG;4、如果只是做纯内存缓存,可以都不用

REDIS主从复制和集群

主从复制和集群参考 https://blog.csdn.net/sinat_26682309/article/details/89197931


goredis对redis的基本操作

//基本操作
func main()  {
	conn,err :=redis.Dial("tcp","127.0.0.1:6379")
	defer conn.Close()
	errCheck(err)

	re,err:= conn.Do("SET","key1","val1")
	errCheck(err)
	fmt.Println(re)

	re,err = redis.String(conn.Do("GET","key1"))
	errCheck(err)
	fmt.Println(re)

	re,err = conn.Do("LPUSH","list1","listval")
	errCheck(err)
	fmt.Println(re)

	re,err = redis.Strings(conn.Do("LRANGE","list1",0,-1))
	errCheck(err)
	fmt.Println(re)
}

//排序
//如果不加STORE list1,则返回一个排序后的列表,list1不改变。如果STORE到其他列表名中,list1不改变
re,err = conn.Do("SORT","list1","STORE","list1")  //返回列表长度

//3秒后list1过期,数据清空
re,err = conn.Do("EXPIRE","list1",3)
//list1距离过期还有几秒
re,err = conn.Do("TTL","list1")

//pipline操作
c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET

//pipline事务操作
c.Send("MULTI")
c.Send("INCR", "foo")
c.Send("INCR", "bar")
r, err := c.Do("EXEC")
fmt.Println(r) // prints [1, 1]

//用scan转换多个返回值为go类型
var value1 int
var value2 string
reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
if err != nil {
    // handle error
}
 if _, err := redis.Scan(reply, &value1, &value2); err != nil {
    // handle error
}

实例1:电话验证码

要求:输入电话号码返回4位验证码,有效期1分钟;同一个号码24小时内只能发送3次。

        var phoneNo = "1888888" //电话号码
	var countKey = phoneNo + ":count" //该电话号码发送次数键名
	var codeKey = phoneNo + ":code"	 //该电话验证码键名

	conn,err :=redis.Dial("tcp","127.0.0.1:6379")
	errCheck(err)
	defer conn.Close()

	//获取该电话号码发送验证码次数
	count,err := redis.Int(conn.Do("GET",countKey))
	errCheck(err)

	//对次数判断
	//如果超过限制次数
	if count > 2 {
		fmt.Println("每日只能发送3次")
		return
	}

	//没有超过限制次数
	//如果是第一次,设置24小时计数清零
	if count == 0 {
		_,err := conn.Do("EXPIRE",countKey,60*60*24)
		errCheck(err)
	}

	//生成验证码
	rand.Seed(time.Now().Unix())
	var code = strconv.Itoa(rand.Int())[:4]

	//在缓存数据库中增加验证码
	_,err = conn.Do("SET",codeKey,code)
	errCheck(err)

	_,err = conn.Do("EXPIRE",codeKey,60)
	errCheck(err)

	//累加验证码发送次数
	count,err = redis.Int(conn.Do("INCR",countKey))
	errCheck(err)

	//返回成功的消息
	fmt.Println("发送成功"+strconv.Itoa(count)+"次。"+"验证码为:"+code)

猜你喜欢

转载自blog.csdn.net/sinat_26682309/article/details/88989145