Skip to content

Commit

Permalink
Merge pull request #93 from rueian/multiplex-single-client
Browse files Browse the repository at this point in the history
feat: multiplex single/sentinel client with default 4 connections to improve latencies
  • Loading branch information
rueian authored Sep 9, 2022
2 parents 2c16111 + 5ecbd52 commit 6dd52de
Show file tree
Hide file tree
Showing 9 changed files with 1,611 additions and 446 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {

## Auto Pipeline

All non-blocking commands sending to a single redis node are automatically pipelined through one tcp connection,
All non-blocking commands sending to a single redis node are automatically pipelined through connections,
which reduces the overall round trips and system calls, and gets higher throughput.

### Benchmark comparison with go-redis v8.11.4
Expand Down
11 changes: 9 additions & 2 deletions hack/cmds/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,12 @@ func printBuilder(w io.Writer, parent, next goStruct) {

if len(next.BuildDef.Parameters) == 1 && next.Variadic {
if next.BuildDef.Parameters[0].Type == "key" {
fmt.Fprintf(w, "\tif c.ks != NoSlot {\n")
fmt.Fprintf(w, "\tif c.ks&NoSlot == NoSlot {\n")
fmt.Fprintf(w, "\t\tfor _, k := range %s {\n", toGoName(next.BuildDef.Parameters[0].Name))
fmt.Fprintf(w, "\t\t\tc.ks = NoSlot | slot(k)\n")
fmt.Fprintf(w, "\t\t\tbreak\n")
fmt.Fprintf(w, "\t\t}\n")
fmt.Fprintf(w, "\t} else {\n")
fmt.Fprintf(w, "\t\tfor _, k := range %s {\n", toGoName(next.BuildDef.Parameters[0].Name))
fmt.Fprintf(w, "\t\t\tc.ks = check(c.ks, slot(k))\n")
fmt.Fprintf(w, "\t\t}\n")
Expand All @@ -640,7 +645,9 @@ func printBuilder(w io.Writer, parent, next goStruct) {
} else {
for _, arg := range next.BuildDef.Parameters {
if arg.Type == "key" {
fmt.Fprintf(w, "\tif c.ks != NoSlot {\n")
fmt.Fprintf(w, "\tif c.ks&NoSlot == NoSlot {\n")
fmt.Fprintf(w, "\t\tc.ks = NoSlot | slot(%s)\n", toGoName(arg.Name))
fmt.Fprintf(w, "\t} else {\n")
fmt.Fprintf(w, "\t\tc.ks = check(c.ks, slot(%s))\n", toGoName(arg.Name))
fmt.Fprintf(w, "\t}\n")
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmds/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func (b Builder) Arbitrary(token ...string) (c Arbitrary) {
// Users must use Keys to construct the key part of the command, otherwise
// the command will not be sent to correct redis node.
func (c Arbitrary) Keys(keys ...string) Arbitrary {
if c.ks != NoSlot {
if c.ks&NoSlot == NoSlot {
for _, k := range keys {
c.ks = NoSlot | slot(k)
break
}
} else {
for _, k := range keys {
c.ks = check(c.ks, slot(k))
}
Expand Down
4 changes: 2 additions & 2 deletions internal/cmds/cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const (
noRetTag = uint16(1<<12) | readonly // make noRetTag can also be retried
mtGetTag = uint16(1<<11) | readonly // make mtGetTag can also be retried
// InitSlot indicates that the command be sent to any redis node in cluster
InitSlot = uint16(1 << 15)
InitSlot = uint16(1 << 14)
// NoSlot indicates that the command has no key slot specified
NoSlot = InitSlot + 1
NoSlot = uint16(1 << 15)
)

var (
Expand Down
Loading

0 comments on commit 6dd52de

Please sign in to comment.