由於需求,需要對容量2w的redis哈希進行整村整取,因此針對hash的常用命令進行效率測試;
測試通過golang語言的redis客戶端庫進行;
對redis的 HGETALL
, HGET
, HMGET
,以及 pipeline下這幾個命令的效率進行測試;測試結果:
效率: HGETALL > HMGET with pipe ≈ HMGET > HGET with pipe > HGET
個人理解:
hmget
和hgetall
時間複雜度應該均是 O(n), 但 hmget基於入參field
數量,而hgetall
基於整個hash數量;對於整取的情況,兩者區別不大;但hmget
需要獲取所有的fields
,因此hgetall
在整取上表現更好;- 對於
hget
, 其時間複雜度爲 O(1), 但每一個key,每一個值均需要單獨獲取;通常批量操作在大規模查詢或設置值時均優於單個命令的操作,通常會有更多的網絡延時等的影響; - 對於
pipeline
, 所有語句一次提交到服務端,因此其消耗更少;
測試代碼如下:
func BenchmarkRedisHash_hgetall(b *testing.B) {
b.StopTimer()
key := "{LicenseCenter}_GLOBAL_TotalAuth"
client := getClient()
b.StartTimer()
for i:=1; i< b.N; i++ {
_ = client.HGetAll(key).Val()
}
}
func BenchmarkRedisHash_hget(b *testing.B) {
b.StopTimer()
key := "{LicenseCenter}_GLOBAL_TotalAuth"
client := getClient()
b.StartTimer()
for i :=0; i<b.N;i++ {
keys := client.HKeys(key).Val()
var result = make(map[string]string)
for _, field := range keys {
val := client.HGet(key, field).Val()
result[field] = val
}
}
}
func BenchmarkRedisHash_hgetWithPipe(b *testing.B) {
b.StopTimer()
key := "{LicenseCenter}_GLOBAL_TotalAuth"
client := getClient()
b.StartTimer()
for i :=0; i<b.N;i++ {
keys := client.HKeys(key).Val()
pipe := client.Pipeline()
var result = make(map[string]string)
for _, field := range keys {
val := pipe.HGet(key, field).Val()
result[field] = val
}
_, _ = pipe.Exec()
}
}
func BenchmarkRedisHash_hmgetWitchPipe(b *testing.B) {
b.StopTimer()
key := "{LicenseCenter}_GLOBAL_TotalAuth"
client := getClient()
b.StartTimer()
for i :=0; i<b.N;i++ {
keys := client.HKeys(key).Val()
pipe := client.Pipeline()
_ = pipe.HMGet(key, keys...).Val()
_, _ = pipe.Exec()
}
}
func BenchmarkRedisHash_hmget(b *testing.B) {
b.StopTimer()
key := "{LicenseCenter}_GLOBAL_TotalAuth"
client := getClient()
b.StartTimer()
for i :=0; i<b.N;i++ {
keys := client.HKeys(key).Val()
_ = client.HMGet(key, keys...).Val()
}
}
測試結果:
goos: windows
goarch: amd64
pkg: ******
BenchmarkRedisHash_hgetall-4 100 84444830 ns/op
BenchmarkRedisHash_hget-4 1 2285130700 ns/op
BenchmarkRedisHash_hgetWithPipe-4 10 178910230 ns/op
BenchmarkRedisHash_hmgetWitchPipe-4 10 149308540 ns/op
BenchmarkRedisHash_hmget-4 10 150108590 ns/op
PASS
如有錯誤,歡迎指正;同時期待告知更好的整取大hash的方式;