天天看點

Redis API——Set功能實踐與性能測試【Go版】

之前說要寫個 Go 語言版本的 Redis 操作 API 和性能測試的系列,沒想到鴿了這麼久才寫了一半。實在實力不濟,不僅需要多充充電,更需要結合實踐,勞逸結合。首先來一個前文回顧:

  • Go語言Redis API基本功能實踐

    2022-06-23

  • Redis API——List功能實踐與性能測試【Go版】

    2022-08-15

按照慣例,我們先介紹常用的 API及其封裝,然後寫個簡單的測試用例,然後再進行性能測試。PS:由于不可描述的原因,本機的磁盤 IO 性能變差,測出的性能參考性較差。

常用 API

由于 set 本身是無序的,是以 set 操作的 API 也是比較簡單的。

SAdd

這個 API 功能是向 set 中添加元素,傳回的也是新增的,也就是說如果新增的元素有重複的,那麼傳回值是不會計算這個重複的key。

// SAdd
//  @Description: 添加集合元素
//  @receiver r
//  @param key
//  @param members
//  @return int64
//
func (r RedisBase) SAdd(key string, members ...interface{}) int64 {
	result, err := r.pool.SAdd(key, members...).Result()
	if err != nil {
		log.Printf("sadd key:%s,members:%s fail\n", key, ftool.ToString(members))
		log.Println(err)
		return base.TestError
	}
	return result
}
           

SCard

SCard 功能是擷取 set 中元素個數,傳回值是 set 中元素個數。

// SCard
//  @Description: 擷取集合元素個數
//  @receiver r
//  @param key
//  @return int64
//
func (r RedisBase) SCard(key string) int64 {
	result, err := r.pool.SCard(key).Result()
	if err != nil {
		log.Printf("scard key:%s fail\n", key)
		log.Println(err)
		return base.TestError
	}
	return result
}

           

SIsMember

SIsMember API 功能是判斷元素是否存在在目前的 set 中。

// SIsMember
//  @Description: 判斷元素是否在集合中
//  @receiver r
//  @param key
//  @param member
//  @return bool
//
func (r RedisBase) SIsMember(key string, member interface{}) bool {
	result, err := r.pool.SIsMember(key, member).Result()
	if err != nil {
		log.Printf("sismember key:%s,member:%s fail\n", key, ftool.ToString(member))
		log.Println(err)
		return false
	}
	return result
}
           

SMembers

SMembers API 功能是擷取 set 中所有元素。

// SMembers
//  @Description: 擷取集合中所有的元素
//  @receiver r
//  @param key
//  @return []string
//
func (r RedisBase) SMembers(key string) []string {
	result, err := r.pool.SMembers(key).Result()
	if err != nil {
		log.Printf("smember key:%s fail\n", key)
		log.Println(err)
		return nil
	}
	return result
}

           

SRem

SRem API 功能是删除集合中的元素,同樣的傳回值也提示删除成功的個數,如果這個元素并不在 set 中,那麼傳回值不包含這個計數。

// SRem
//  @Description: 删除集合元素
//  @receiver r
//  @param key
//  @param members
//
func (r RedisBase) SRem(key string, members ...interface{}) int64 {
	result, err := r.pool.SRem(key, members...).Result()
	if err != nil {
		log.Printf("srem key:%s members:%s fail\n", key, ftool.ToString(members))
		log.Println(err)
		return base.TestError
	}
	return result
}

           

SPop & SPopN

SPop API 是随機擷取 set 中的一個元素,并且會删除改元素。

SPopN API 是随機擷取 N 個元素,并且删除該元素,如果 N 的值大于目前元素個數,那麼有多少傳回多少。

// SPop
//  @Description: 随機傳回集合中的元素,并且删除傳回的元素
//  @receiver r
//  @param key
//  @return string
//
func (r RedisBase) SPop(key string) string {
	result, err := r.pool.SPop(key).Result()
	if err != nil {
		log.Printf("spop key:%s fail\n", key)
		log.Println(err)
		return base.Empty
	}
	return result
}
           

API 示範用例

func TestSet(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "funset"
	add := pool.SAdd(key, ftool.RandomStr(10), ftool.RandomStr(3), "FunTester")
	log.Println(add)
	log.Printf("FunTester 是否存在 %t", pool.SIsMember(key, "FunTester"))
	log.Println(pool.SCard(key))
	members := pool.SMembers(key)
	for _, s := range members {
		log.Println(s)
		if ftool.RandomInt(2) == 1 && s != "FunTester" {
			pool.SRem(key, s)
		}
	}
	log.Println(pool.SRem(key, "FunTester", "000000000"))
	log.Println(pool.SPop(key))
	log.Println(len(pool.SPopN(key, 1000)))
}

           

性能測試

func TestSetPer(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "funsetper"
	execute.ExecuteRoutineTime(func() {
		add := int(pool.SAdd(key, ftool.RandomStr(10), ftool.RandomStr(3)))
		for i := 0; i < add; i++ {
			pool.SPop(key)
		}

	}, 20, 5)
}

           
=== RUN   TestSetPer
2022/09/18 22:31:09 Redis 連接配接成功
2022/09/18 22:31:09 确認連接配接成功!
2022/09/18 22:31:29 總耗時: 19.999000
2022/09/18 22:31:29 請求總數: 330634
2022/09/18 22:31:29 QPS: 16532.526626
--- PASS: TestSetPer (20.00s)
PASS
           

繼續閱讀