• Redis API——List功能实践与性能测试【Go版】


    前文提到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原创专题集锦

    阅读原文,跳转我的仓库地址

  • 相关阅读:
    Hadoop之HDFS的热备份
    Hadoop之联邦HDFS
    Hadoop之HDFS如何保证高可用
    Hadoop之HDFS的读流程
    Hadoop之HDFS数据写流程和写失败的情况
    Hadoop之HDFS的block、packet、chunk
    Hadoop之HDFS的元数据冷备份(CheckPoint)
    当ZooKeeper作为Dubbo的注册中心的时候,是怎么工作的?
    Dubbo
    mysql磁盘满了如何恢复
  • 原文地址:https://www.cnblogs.com/FunTester/p/16588220.html
Copyright © 2020-2023  润新知