I'm learning Redis and trying to use Redis (cluster-mode) transaction wrap up several operations. The library I use is go-redis v9.5.1. The code two wrap four commands in a transaction, then return the current server time for another command insert into a sorted set.
ctx := context.Background()
pipe := s.c.TxPipeline()
// New token is added to the tail of the queue
pipe.Incr(ctx, s.tailKey(Id, Key))
pipe.Get(ctx, s.headKey(Id, Key))
pipe.Get(ctx, s.resetKey(Id, Key))
pipe.Time(ctx)
cmds, err := pipe.Exec(ctx)
if err != nil && !errors.Is(err, redis.Nil) {
log.Error().Err(err).Msg("redis")
return 0, 0, nil, err
}
However, when I run MONITOR command to debug on Redis, it print out the following commands:
1710299128.368998 [0 192.168.73.113:58490] "multi"
1710299128.369037 [0 192.168.73.113:58490] "incr" "{KEY}:tp"
1710299128.369046 [0 192.168.73.113:58490] "get" "{KEY}:hp"
1710299128.369050 [0 192.168.73.113:58490] "get" "{KEY}:rs"
1710299128.369054 [0 192.168.73.113:58490] "exec"
1710299128.369800 [0 192.168.73.113:58490] "multi"
1710299128.369810 [0 192.168.73.113:58490] "time"
1710299128.369812 [0 192.168.73.113:58490] "exec"
It seems like the lib break my transaction into two multi-exec command blocks. To cross-check I debugged other part of my code. I also found another similar situation that one transaction translated into two multi-exec block.
_, err = s.c.TxPipelined(ctx, func(p redis.Pipeliner) error {
p.ZAddNX(ctx, s.queueKey(TEST, KEY), redis.Z{Member:t.ID, Score: timeToRedisScore(t.CreatedTime)})
p.HSet(ctx, s.sessionKey(TEST, KEY, t.ID), t.ToHash())
p.Expire(ctx, s.sessionKey(TEST, KEY, t.ID), s.TTL)
return nil
})
translated to
1710299128.370271 [0 192.168.73.113:58490] "multi"
1710299128.370297 [0 192.168.73.113:58490] "zadd" "KEY:q" "nx" "1710299128369" "c5c86e7d-ed3d-4e90-86da-18a4a15f4e1c"
1710299128.370307 [0 192.168.73.113:58490] "exec"
1710299128.370948 [0 192.168.73.113:58490] "multi"
1710299128.370979 [0 192.168.73.113:58490] "hset" "KEY:{c5c86e7d-ed3d-4e90-86da-18a4a15f4e1c}:sess" "GID" "TEST" "GRD" "LOGIN_QUEUE" "T" "c5c86e7d-ed3d-4e90-86da-18a4a15f4e1c" "1710299128369"
1710299128.371000 [0 192.168.73.113:58490] "expire" "KEY:{c5c86e7d-ed3d-4e90-86da-18a4a15f4e1c}:sess" "60"
1710299128.371008 [0 192.168.73.113:58490] "exec"
The only similarity between those two cases I can think of is the one put into one multi-exec block shared the same hash tag ({KEY} in first case and {c5c86e7d-ed3d-4e90-86da-18a4a15f4e1c} in second case).
I tried to check the client implementation but didn't find any specific process for hash tag (maybe I'm dumb and missed it...). Does anyone saw similar issue before?
Also, what keyslot does the TIME command hash to? It doesn't seems contains a key...XD
Any advice and help would be appreciated, thanks:-).