It would be great to have a support for multiple redis Instances.
What i was thinking is having a configuration in settings.php like
"redis_servers" similar to memcache_servers
or
$conf['redis_servers'] = array(
'default' => array(
'host' => '',
'port' => '',
'password' => ''
),
'db2' => array(
'host' => '',
'port' => '',
'password' => ''
)
);
We can access these servers by
$conn = Redis_Client::getClient('db2'); // Defaults to 'default'
Redis is single core and i am aware that, it so fast, it can't even use its computation power. But having the flexibility to manage data across different redis instance between different servers or same servers makes redis ever faster, and i read, its best to run 1 redis instance per 2 core (One for the writting to disk).
Multiple Redis backends would also allow spearation of individual cache bins into separate Redis instances similar to what MongoDB cache backend allows (eg. one with disk persistance and another without, depending on warmup times). Depending on number of items and storage availability, it might be also a good fit for a shared and truly expirable 'cache_form' bucket and solve some old known 'cache_form' headaches for some setups.
It will also be useful for Master - Client, and writing on master and reading on client kindof setup.
Comment | File | Size | Author |
---|---|---|---|
#19 | redis-cluster-2071521-19.patch | 7.76 KB | kala4ek |
Comments
Comment #1
chia CreditAttribution: chia commentedBy changing this singleton class, we can make it work.
Or we can make it more flexible and make it like drupal.
I have seen people have master-slave redis servers pairs.
we can make it like Database::getConnection('default', 'default/master/slave');
Comment #2
pounardGood idea supporting multiple Redis instances but this won't be for the first real stable release I am preparing right now. Postponing until the stable release comes out. This issue is still open for discussion.
Comment #3
richwandell CreditAttribution: richwandell commentedCurrently the 2 implementations of redis phpredis and predis use the "keys" command which is not supported in redis clustered implementations.
Something like this could be used to grab keys from all the instances. Then just change all the lines in the clear function from "$client->keys" to "$this->keys"
Also using Predis, the library does not support high availability. If one redis server is down the whole thing breaks. We should implement a system for connecting to the remaining redis servers if one is down.
Comment #4
pounardAs soon as you want to do sharding or something similar, you loose a lot of commands, not only KEYS but WATCH/MULTI/EXEC blocks as well. This module, as it exists, can *not* support this. The only multi-server installation it can support is basic master/slave replication. Supporting any other configuration would mean loosing transactions. As long as you use it for cache, and provide locking throught a single server, it might be OK
, but the cache backend implementation the module provides would need a serious refactor.EDIT: Actually the cache backend uses MULTI blocks only for pipelining so I guess it would be easier than I think.Another thing to consider is that it's might be easier to use a proxy such as twemproxy for high-availibility instead of relying on PHP code to do this: PHP code would remain minimal and easy to maintain for the cost of having to install such proxy.
Comment #5
vinmassaro CreditAttribution: vinmassaro commented@pounard: does this module work with twemproxy? I have twemproxy running and can set/get keys via redis-cli, but setting Redis configuration in settings.php to point at the twemproxy port returns
RedisException: read error on connection in Redis->watch()
.Comment #6
pounardThis is probably because of the WATCH command, twemproxy doesn't support transactions. I never tested it myself using it, may be I should and try to make it run using it! Beware that it is impossible to run the lock backend because locking relies on transactions, are you using the cache backend only or the lock inc as well?
Comment #7
vinmassaro CreditAttribution: vinmassaro commentedHmm, I followed the README and other guides found for configuring Redis module for Drupal. All seem to set both, so this is what I have been using:
At this point, are all implementations of Redis with Drupal currently only using a single Redis cache instance?
Comment #8
pounardAt this point you are using the lock backend but not the cache backend, read the readme file again, you need to set the default cache backend class:
And comment the following line before retrying:
It should then work I guess.
Comment #9
vinmassaro CreditAttribution: vinmassaro commentedOh, I have all that other configuration, I just didn't include it. Can you explain what the lock backend does and why it can't be used in this situation?
Comment #10
pounardLocking needs write operations to be atomic in order to ensure that one and only one concurrent thread can get the same lock at the same time, for this I used the MULTI/WATCH/EXEC Redis blocks which ensure atomicity of the transaction when correctly used. Transactions cannot be ensured in an environment where you dispatch information into multiple servers, this is due to sharding and partionning, you cannot ensure atomicity of a single transaction using keys accross multiple different servers, that's why twemproxy don't support transactions.
Comment #11
vinmassaro CreditAttribution: vinmassaro commentedOk, this partially works with the lock backend commented out. Some issues:
Not sure there's anything we can do here until these commands are added to twemproxy. We will likely just run a single dedicated Redis instance for now. Thoughts?
Comment #12
pounardAs I said, I think that it will need a major rewrite to be able to work using multiple instances, especially when doing sharding.
But you can still use master-slave replication if you really need redundancy, I'd advise you to read this: http://redis.io/topics/replication
Comment #13
pounardThe problem in our case (cache usage) will always be the cache clear operations: if we want to be able to drop everything from a cache bin, we need to register its keys somewhere to be able to send the clear command. This where the problem starts because as soon as we try to register all keys somewhere, we always end up with a non scalable storage and/or algorithm for clearing the caches, or completly change the way we store keys and maybe use set or hashes instead, but that'd need a complete rewrite and would probably make sharding inneficient.
Comment #14
richwandell CreditAttribution: richwandell commented@vinmassaro i was able to hack this module into working with multiple redis instances running by using Predis instead of twemproxy and extending the predis classes to create my own redis backend for the module. It's really easy to do, just override the keys methods and any other methods that aren't supported by redis cluster to send those commands individually to each node and return a merged array of keys. Predis supports clustering out of the box, the only thing it's missing is the commands that are not a part of the redis cluster specification... just fix that
Comment #15
vinmassaro CreditAttribution: vinmassaro commented@richwandell: thanks for the info. We ended up going with a master Redis instance and a replicated slave with failover via Redis Sentinel. This seems to be sufficient for our needs as an LRU cache store.
Comment #16
kala4ek@richwandell
Did you have any success with hacking? If 'yes', could you share your solution?
Comment #17
amonteroWhat's the status on this? What's the maintainer's stance on commiting this if accomplished?
I see the discussion going the master/slave sharding path, but multiple Redis backends would also allow spearation of individual cache bins into separate Redis instances alas MongoDB cache backend allows (eg. one with disk persistance and another without, depending on warmup times).
Depending on number of items and storage availability, it might be also a good fit for a shared and truly expirable 'cache_form' bucket and solve some old known 'cache_form' headaches for some setups.
Setting this back to active to reopen discussion and attaching to 7.x-2.12 (could not found 7.x-2.x).
Comment #18
pounardTo be honest, I never wanted to implement this feature, but I might give it a try in the 3.x release, anyway, I'm still leaving this opened since a lot of people seem to be interested, it makes me think I should do it.
I will try, when I'll have the time to do it, may be in a few weeks.
Comment #19
kala4ekHello guys, I make some patch for cluster support.
It works with sharding type of cluster.
Patch works only with Predis library, please check it.
It's very very beta patch :)
Sample of settings.php file:
Comment #20
pounardI am actually working on multi-server configuration :)
Comment #21
pounardThis definitely won't be a feature of the 2.x branch.
Comment #22
pounardAs a side note: if your need is to have a distributed system, 3.x version is able to use a shard through proxy assisted sharding, and connecting to a redis-cluster is a planned feature, see #2556097: Support cluster connections.
Comment #23
pounardI'm closing this issue now, because I won't implement it ever in the 3.0 release. 4.0 may bring it someday.
Comment #24
amonteroSetting to 'postponed' instead, to help keep track of the request, as done for #2556097: Support cluster connections.
It would be a pity to lose this thread unnoticed when the time comes.
Comment #25
pounardFair enough.
Comment #26
amonteroComment #27
pounardI am sorry, this will not get into 7.x-3.x, I am working on a new PHP library outside of Drupal: https://github.com/makinacorpus/redis-bundle which provides a more fully-featured connector for this, which also provides the Drupal 7 backend. Future 7.x-4.x version will be this library integration.