前文提到Go语言Redis API基本功能实践,以及后续的学习实践计划,由于总总原因耽搁了许久。终究是计划赶不上变化,学完Go语言操作Redis的常用功能之后,我打算把API实践、封装、简单性能测试场景放在一起写。
今天分享一下Redis list常用操作API的实践和性能测试,API的封装会放在文末。
常用API实践
LPush、LPush、LPush、LPush
关于API的功能,看名字就能够明白八九不离十。两组变量:左和右,推送和获取。
下面是我写了一个测试用例,均测试通过。
func TestPushPop(t *testing.T) {
var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
var key = "fun"
var value = "abc"
pool.LPush(key, value)
pop := pool.LPop(key)
assert.Equal(t, pop, value)
}
func TestPushPop2(t *testing.T) {
var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
var key = "fun"
var value = "abc"
pool.RPush(key, value)
pop := pool.RPop(key)
assert.Equal(t, pop, value)
}
XLen
这是一个获取list长度的API。测试用例如下:
func TestLen(t *testing.T) {
var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
var key = "fun"
var value = "FunTester"
len1 := pool.LLen(key)
pool.LPush(key, value)
len2 := pool.LLen(key)
pool.LPop(key)
len3 := pool.LLen(key)
assert.Equal(t, len1, len3)
assert.Equal(t, len1, len2-1)
}
LRange
获取某个范围的list数据,获取不会删除原始数据。用例如下:
func TestLRange(t *testing.T) {
var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
var key = "fun"
var value = "FunTester"
pool.Del(key)
for i := 0; i < 10; i++ {
pool.RPush(key, value+strconv.Itoa(i))
}
lRange := pool.LRange(key, 1, 3)
for _, s := range lRange {
log.Println(s)
}
}
日志输出如下:
=== RUN TestLRange
2022/08/13 17:13:31 Redis 连接成功
2022/08/13 17:13:31 确认连接成功!
2022/08/13 17:13:31 FunTester1
2022/08/13 17:13:31 FunTester2
2022/08/13 17:13:31 FunTester3
--- PASS: TestLRange (0.00s)
后来还有一些不常用的API(对于我来讲)这里就不过多展示了,下面进入性能测试环节。
性能测试
这里我只设计了一个性能测试用例,添加和删除。这次使用的时间作为限制条件的压测模型。
func TestPushPopPerf(t *testing.T) {
var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
var key = "fun"
var value = "FunTester"
execute.ExecuteRoutineTime(func() {
pool.LPush(key, value)
pool.RPop(key)
}, 20, 2)
}
控制台输出:
=== RUN TestPushPopPerf
2022/08/13 17:22:40 Redis 连接成功
2022/08/13 17:22:40 确认连接成功!
2022/08/13 17:23:00 总耗时: 20.001000
2022/08/13 17:23:00 请求总数: 532029
2022/08/13 17:23:00 QPS: 26600.119994
--- PASS: TestPushPopPerf (20.00s)
PASS
API封装
下面是我针对Redis API的封装源码,大家有兴趣的可以阅读原文去我的仓库。
package redis
import (
"funtester/base"
"log"
)
// LPush
// @Description: 从列表左边插入数据
// @receiver r
// @param key
// @param value
// @return int64
//
func (r RedisBase) LPush(key string, value interface{}) int64 {
result, err := r.pool.LPush(key, value).Result()
if err != nil {
log.Printf("LPush:%s value: %s 失败\n", key, value)
log.Println(err)
return base.TestError
}
return result
}
// RPush
// @Description:从列表右边插入数据
// @receiver r
// @param key
// @param value
// @return int64
//
func (r RedisBase) RPush(key string, value interface{}) int64 {
result, err := r.pool.RPush(key, value).Result()
if err != nil {
log.Printf("RPush:%s value: %s 失败\n", key, value)
log.Println(err)
return base.TestError
}
return result
}
// LPop
// @Description: 从列表左边删除第一个数据,并返回删除的数据
// @receiver r
// @param key
// @param second
// @return string
//
func (r RedisBase) LPop(key string) string {
result, err := r.pool.LPop(key).Result()
if err != nil {
log.Printf("LPop:%s 失败\n", key)
log.Println(err)
return base.Empty
}
return result
}
// RPop
// @Description: 从列表的右边删除第一个数据,并返回删除的数据
// @receiver r
// @param key
// @param second
// @return string
//
func (r RedisBase) RPop(key string) string {
result, err := r.pool.RPop(key).Result()
if err != nil {
log.Printf("RPop:%s 失败\n", key)
log.Println(err)
return base.Empty
}
return result
}
// LLen
// @Description: 返回列表的大小
// @receiver r
// @param key
// @return int64
//
func (r RedisBase) LLen(key string) int64 {
result, err := r.pool.LLen(key).Result()
if err != nil {
log.Printf("LLen :%s 失败\n", key)
log.Println(err)
return base.TestError
}
return result
}
// LRange
// @Description:返回列表的一个范围内的数据,也可以返回全部数据
// @receiver r
// @param key
// @param start
// @param end
// @return []string
//
func (r RedisBase) LRange(key string, start, end int64) []string {
result, err := r.pool.LRange(key, start, end).Result()
if err != nil {
log.Printf("LRange :%s 失败\n", key)
log.Println(err)
return nil
}
return result
}
// LRem
// @Description:删除列表中的数据
//从列表左边开始删除, 如果出现重复元素,仅删除1次,也就是删除第一个(key,1,"FunTester")
// 如果存在多个,则从列表左边开始删除2个100(key,2,"FunTester")
// 如果存在多个,则从列表右边开始删除2个100(key,-2,"FunTester")
// 删除所有(key,0,value)
// @receiver r
// @param key
// @param count
// @param value
// @return int64
//
func (r RedisBase) LRem(key string, count int64, value interface{}) int64 {
result, err := r.pool.LRem(key, count, value).Result()
if err != nil {
log.Printf("LRem :%s count: %d value: %s 失败\n", key, count, value)
log.Println(err)
return base.TestError
}
return result
}
// LIndex
// @Description:根据索引坐标,查询列表中的数据
// @receiver r
// @param key
// @param index 索引,从0开始算
// @return string
//
func (r RedisBase) LIndex(key string, index int64) string {
result, err := r.pool.LIndex(key, index).Result()
if err != nil {
log.Printf("LIndex :%s index: %d 失败\n", key, index)
log.Println(err)
return base.Empty
}
return result
}
// LInsertBefore
// @Description:在指定位置插入数据
// @receiver r
// @param key
// @param pivot
// @param value
// @return int64
//
func (r RedisBase) LInsertBefore(key string, pivot, value interface{}) int64 {
result, err := r.pool.LInsertBefore(key, pivot, value).Result()
if err != nil {
log.Printf("LInsertBefore :%s pivot: %s value:%s 失败\n", key, pivot, value)
log.Println(err)
return base.TestError
}
return result
}
// LInsertAfter
// @Description:在指定位置插入数据
// @receiver r
// @param key
// @param pivot
// @param value
// @return int64
//
func (r RedisBase) LInsertAfter(key string, pivot, value interface{}) int64 {
result, err := r.pool.LInsertAfter(key, pivot, value).Result()
if err != nil {
log.Printf("LInsertAfter :%s pivot: %s value:%s 失败\n", key, pivot, value)
log.Println(err)
return base.TestError
}
return result
}
FunTester原创专题集锦
阅读原文,跳转我的仓库地址