Open nickchomey opened 2 months ago
As expected, this works for using the dragonflydb image instead of redis. I simply changed the image, and commented-out the deploy:
section as that seems to be for docker swarm and breaks with dragonflydb. My wordpress app, redis-cli, redis-benchmark all connect automatically. It isn't using any config files, but that could surely be solved easily enough.
#ddev-generated
volumes:
redis:
name: ddev-${DDEV_SITENAME}-redis
labels:
com.ddev.site-name: ${DDEV_SITENAME}
services:
redis:
container_name: ddev-${DDEV_SITENAME}-redis
hostname: ddev-${DDEV_SITENAME}-redis
# image: redis:7.4-alpine
# command: /etc/redis/conf/redis.conf
image: docker.dragonflydb.io/dragonflydb/dragonfly
volumes:
- ".:/mnt/ddev_config"
- "ddev-global-cache:/mnt/ddev-global-cache"
- "./redis:/etc/redis/conf"
- "redis:/data"
expose:
- 6379
networks:
- default
# deploy:
# resources:
# limits:
# cpus: "2.5"
# memory: "768M"
# reservations:
# cpus: "1.5"
# memory: "512M"
restart: "no"
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
swapping in image: ghcr.io/microsoft/garnet
works equally seamlessly. So, I see no reason why we couldn't make this happen...
redis-benchmark
performance is vastly worse for those than redis, but that's surely just due to not using any configuration at all.
As suggested in the OP, I think the most approachable way to implement this would be something like a ddev redis backend
command that can swap between the kv backends. Regardless of how it is done, I suppose it would need to restart the container in order build the appropriate image. Surely just the redis container could be restarted rather than the whole ddev project
Some options for selecting the image:
docker_compose.redis.yaml
file, which contains a placeholder for the image that gets populated via an environment variable such as ${DDEV_REDIS_IMAGE}
. The command could just re-set the env variable before restarting the container/.ddev
root directory? The latter is probably preferrable as it would allow for different docker configs for each backend - not sure if that's necessary or not? Probably is, especially if you want to do something like replication across different containers to simulate a cluster of app/redis/db servers.
Either way, I actually don't see much reason why the addon couldn't "officially" support the most popular backends - redis, dragonfly, valkey, garnet etc... Just include their docker compose files or image name, depending on which switching mechanism is implemented. People could request more be added, or an env var extension could be implemented.
The details are less important at this point than the willingness to see something like this.
I see that there's an active PR for making ddev get more extensible/flexible. Best to wait for it to get merged before proceeding with anything here.
Nick. Again - thanks for the detailed and st8-to-the-point writeup. I'd rather build out separate extensions for both DragonflyDB and Valkey - and let users choose which one to use. Less overhead in maintaining three extensions than having one-in-all solution.
@rfay I'd like to get your thoughts on this? :)
That's fine. I had assumed there would be less effort required to maintain one addon, but defer to your knowledge of ddev. It was worth bringing up at least and poking around a bit with the idea.
It is a worthy thought to see if we could consolidate all the redis clones (and redis versions?) into one add-on.
I'd love to see a review of @stasadev 's
wrt this idea. Could you try it out and see if you think that PR would give you enough customization capability (and persistence of customization) and do a review there?
Related PR that goes with that DDEV PR:
The main hurdle I see to adding something like this to this addon is how to define and handle each backend's config file(s). It has to be assumed that none of them are actually compatible with each other, it's just the api and port that are compatible. In fact, when I used valkey, it failed when I used the existing redis config files, even though valkey is apparently a straight fork of redis. Changing to the original version of valkey didn't help.
I've also already had issues with a getting a custom config file working for a few of the backends, but I'm sure that can be solved. But it's not something that we should offload on users.
So, it would probably be best to (upon request/PR contribution) add "official" support for different backends where the required base config file(s) and image string are added to a common parent directory, and then the addon exposes a command to just toggle which backend will be used when starting the containers.
I'll follow up when I've had time to look at the addon get settings pr, to understand it and see how it might be useful here. It would be a good "real world" test case for it to help refine it's implementation, if needed.
I just shared thoughts on that PR. I think .env.redis
variables would be a good way to handle this feature request, but dont think the way that it is currently implemented is appropriate. Ive made some detailed observations/suggestions there. We'll see where it goes
With Redis changing its license recently, a slew of Redis-compatible KV stores were forked/created/released (in addition to other promising ones that already existed). Decent enough background on that here.
The thought here is to make this more of a
ddev kv
command rather than just Redis (though it can stay asddev redis
), which could allow users to simply toggle between different Redis-compatible KV stores and their application code would presumably not need to change at all - it would still point toredis:6379
(or the unix socket equivalent).This would make it easier to experiment with the various stores, without needing to create additional ddev addons or other project-specific custom dockerfiles.
In theory it should be as easy as just changing the docker image in use...
Here's DragonflyDB's Docker Compose installation instructions
Basically just download this
docker-compose.yaml
file and rundocker compose up
and then connect to it withredis-cli
- it Just Works (tm) withlocalhost:6379
defaults.(Interesting that they have an explicit note to use a host network for better performance! Probably relevant to #30, though likely not possible to implement in the context of DDEV).
I have to assume the rest of the Redis-compatible KV stores are similarly seamless drop-in replacements.
https://github.com/valkey-io/valkey - Linux Foundation Redis Fork https://github.com/Snapchat/KeyDB - Snapchat's redis fork, which now has multithreading, active replicatoin and more. A bit stale/unmaintained though https://github.com/dragonflydb/dragonfly - Very promising mutlithreaded Redis-compatible store https://github.com/microsoft/Garnet - From microsoft, and has very promising benchmark stats and features https://github.com/nalgeon/redka - Somewhat Redis-compatible, that sits on SQLite. Very interesting. https://github.com/apache/kvrocks - From apache. Distributed via async replication https://github.com/Tencent/Tendis
And PLENTY more. The point is not to officially find and support them all, but to make it easy to swap them in and out within the same redis DDEV container.
Perhaps the image could be defined in a redis-specific config file or project environment variable? Or just put all the docker compose files in the same directory and a
ddev redis backend {dbname}
command could toggle between them. Or something else - I'm sure there's a good, easy, flexible, robust way to implement this.If there's any interest in this, I'll fiddle around to see how it might work.