Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Redis replica without cluster mode #433

Closed
pranas opened this issue Dec 1, 2016 · 13 comments
Closed

Use Redis replica without cluster mode #433

pranas opened this issue Dec 1, 2016 · 13 comments

Comments

@pranas
Copy link

pranas commented Dec 1, 2016

We have Redis master + replica configuration without using cluster mode. We would like to route reads to both based on latency. I see go-redis has this feature but it seems it's only available with cluster mode. Any plans to support it on non cluster client?

@vmihailenco
Copy link
Collaborator

No, I am not aware of any way to achieve this. And since this is essentially a Redis Cluster with 2 nodes (master+slave) I don't see much value in supporting this in standard client...

@jpza
Copy link

jpza commented Jan 11, 2018

It's quite common for people to have Redis read-replicas without Redis being in cluster-mode, at least for now since it guarantees strong consistency and is operationally simpler.

Another issue, #673, is also asking for this feature.

If you don't need master sharding and you just want to scale out reads than this non-cluster mode setup of read-replicas without cluster-mode is more performant. Since the demand for this feature is present and it has been implemented by https://github.com/luin/ioredis I am bumping this.

This difficulty I see here is how to iterate over read-replicas.

@pranas
Copy link
Author

pranas commented Jan 12, 2018

It would be great if you allow to choose different routing strategies. For our use case we want routing by latency (which you already have in cluster client) while others might want round robin routing.

By the way, glad you saw the need for this feature. Thanks!

@cyriltovena
Copy link

I'm having the same need, would love to see this feature of using read-replica without sentinel/cluster.

@ramonberrutti
Copy link
Contributor

@Kuqd I have the same problem. I solve now having two connections. redisClient and redisClientRead

@pranas
Copy link
Author

pranas commented May 15, 2018

We also have a similar workaround. Since we have multiple read replicas we initialise multiple go-redis clients, put them in a slice and then randomly pick one for read operations.

@cyriltovena
Copy link

cyriltovena commented May 18, 2018

@pranas @ramonberrutti This is good workaround. Thanks.

Though for my use case it requires a bit of refactor since I'm reading and writing a lot. I'll think about it thanks.

@vmihailenco
Copy link
Collaborator

See https://godoc.org/github.com/go-redis/redis#example-NewClusterClient--ManualSetup. It uses 2 master nodes, but using single master should work too.

@FarhanSajid1
Copy link

We also have a similar workaround. Since we have multiple read replicas we initialise multiple go-redis clients, put them in a slice and then randomly pick one for read operations.

Has go-redis added support, or is this the solution at the moment?

@michal-mazurkiewicz
Copy link

Up!

Is there any out of the box solution to use redis with read-replica without cluster mode?

@Av1shay
Copy link

Av1shay commented Jun 21, 2023

Any updates on this?
It is really common to use redis with read replica without cluster mode

@I70l0teN4ik
Copy link

Another bump here.
Cheapest AWS ElastiCache Redis with 2 read replica in diff zones is more then enough for my app needs to fulfill the redundancy and keep all the data needed.
Cluster mode is definitely an overkill for that scenario. Don't get why that's not supported still :(

@gaston-haro
Copy link

Is it not this how we are expected to attend this scenario?

clusterSlots := func(ctx context.Context) ([]redis.ClusterSlot, error) {
		slots := []redis.ClusterSlot{
			// "virtual" cluster node with 1 master and 1 slave.
			{
				Start: 0,
				End:   16383,
				Nodes: []redis.ClusterNode{{
					Addr: ":7000", // master
				}, {
					Addr: ":8000", // 1st slave|read replica
				}},
			},
		}
		return slots, nil
	}

	rdb := redis.NewClusterClient(&redis.ClusterOptions{
		ClusterSlots:  clusterSlots,
		RouteRandomly: true,
	})
	rdb.Ping(ctx)

(similar example but with cluster mode enabled from de docs

go-redis/example_test.go

Lines 81 to 120 in 2512123

func ExampleNewClusterClient_manualSetup() {
// clusterSlots returns cluster slots information.
// It can use service like ZooKeeper to maintain configuration information
// and Cluster.ReloadState to manually trigger state reloading.
clusterSlots := func(ctx context.Context) ([]redis.ClusterSlot, error) {
slots := []redis.ClusterSlot{
// First node with 1 master and 1 slave.
{
Start: 0,
End: 8191,
Nodes: []redis.ClusterNode{{
Addr: ":7000", // master
}, {
Addr: ":8000", // 1st slave
}},
},
// Second node with 1 master and 1 slave.
{
Start: 8192,
End: 16383,
Nodes: []redis.ClusterNode{{
Addr: ":7001", // master
}, {
Addr: ":8001", // 1st slave
}},
},
}
return slots, nil
}
rdb := redis.NewClusterClient(&redis.ClusterOptions{
ClusterSlots: clusterSlots,
RouteRandomly: true,
})
rdb.Ping(ctx)
// ReloadState reloads cluster state. It calls ClusterSlots func
// to get cluster slots information.
rdb.ReloadState(ctx)
}
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants