4

We want to save a few bucks and share our 1GB dedicated Azure Redis Cache between Development, Test, QA and maybe even production.

Is there a better way than prefixing all keys with an environment string like "Dev_[key]", "Test_[key]" etc.

We are using the StackExchange Redis client for .NET.

PS: We tried using the cheap 250GB (Shared infrastructure), but had very slow performance. Read operations were consistent between 600-800ms... without any load (for a ~300KB object). Upgrading to dedicated 1GB services changed that to 30-40ms. See more here: StackExchange.Redis with Azure Redis is unusably slow or throws timeout errors

Community
  • 1
  • 1
Thomas Jespersen
  • 11,493
  • 14
  • 47
  • 55

2 Answers2

1

One approach is to use multiple Redis databases. I'm assuming this is available in your environment :)

Some advantages over prefixing your keys might be:

  • data is kept separate, you can flushdb in test and not touch the production data
  • keys are smaller and consume less memory

The main disadvantage would be not taking advantage of multiple cores, like you could do if you ran multiple instances of Redis on the same server. Obviously not an issue in this case. Also note that this feature is not deprecated, like one of the answers suggests.

Another thing I've seen people complain about is that databases are numbered, they don't have meaningful names. Some people create a hash in database 0 that maps each number to a name.

Community
  • 1
  • 1
Sunil D.
  • 17,983
  • 6
  • 53
  • 65
  • I've implemented it with a combination of DatabaseId and the WithKeyPrefix extension method. I used DatabaseID for environment, and then the WithKeyPrefix (https://github.com/StackExchange/StackExchange.Redis/blob/master/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseExtension.cs) for schema version. So when deploying new assemblies with new properties on classes the old cache is automatic invalidated. – Thomas Jespersen Jul 01 '15 at 07:45
0

Here is another idea to save some bucks: use separate Redis cache machines for each environment - so no problems with the keys, but stop them when you don't use them, like in the weekend and during nights. Probably more than 50% of the time you are not using them. I think it would be easy to start and stop them with some PowerShell script, we are using AWS and here it is possible.

Now from what I see the Redis persistence in Azure is not enabled, but they started working on it http://feedback.azure.com/forums/169382-cache/status/191763 - it would be nice to do a RDB snapshot before stopping and then on start to load it. So if you need to save some values and reload them on start you should do it manually (with your own service).

Liviu Costea
  • 3,624
  • 14
  • 17
  • In Azure Redis is Platform as a Service (PaaS), so when we provision "a server" you just get a URI like (myredisdb.redis.cache.windows.net) and a password. Not much more you can do. We could deprovision it, but you can't start/stop AFAIK. Also managing this for 10+ environments would be a hassle. – Thomas Jespersen Jun 26 '15 at 07:27
  • And that's all you need an URI. I didn't mean to install your own Redis to start and stop but to start and stop your service as needed. And the URI you get from Azure Redis you just modify in your DNS or in Azure DNS if you are using it. For example when you start a Redis for your test env you should have a dns entry - CNAME with test-redis.your-domain.com and you just update that with the new Azure Redis URI. Yes, it might be a little more complicated, but you can automate a lot. – Liviu Costea Jun 26 '15 at 08:25
  • But that does not solve my problem, where the same Redis Cache instance is shared between environments. I still need to prefix keys that they don't conflict between environments. Or maybe I don't understand what... and I'm pretty sure this is not "the solution" here. – Thomas Jespersen Jun 26 '15 at 11:31
  • You are right, it doesn't solve your problem with the same redis instance. I suggested another thing because I thought your real issue is saving some money and what I am actually suggesting is some auto scaling solution because this is what cloud is all about. – Liviu Costea Jun 26 '15 at 11:41
  • I am trying to save money. But I the reason your suggestion does not work in Azure is that it's "Platform as a Service". You don't get a server which you can start & stop. You provision an instance of a cache and get a global unique endpoint/uri... you don't know if its Linux or Windows. It takes 5-10 minutes to provision a new instance, and you don't have guarantee that the endpoint/uri is not taken by somebody else. Also you get new auto generated keys every/password time. So this solution is slow and it requires a lot of Azure spefic code. And finally you end up with a bigger bill :) – Thomas Jespersen Jul 01 '15 at 07:56
  • Here is a simple ps script that starts a Redis service, gets its keys and then stops it: https://azure.microsoft.com/en-gb/documentation/articles/cache-howto-manage-redis-cache-powershell Once the Redis service is started you can take its params and update your env config. I do think it is possible, we are doing similar things on AWS. Yes, it will take minutes to have everything setup, but it can be started automatically before everybody starts working and stopped after everyone leaves. Yes, it will require Azure specific code because of Azure API and yes you might pay more than a single Redis – Liviu Costea Jul 01 '15 at 09:11
  • This script does not stop at start the Redis services. It provisions and deprovisions a Redis Cache instance. It takes 5-10 minutes to run (maybe even 15 minutes).We could spin up a Linux Server and install a Redis Cache, and create as many instances we like for very small money. But we don't want to administrate servers (PaaS vs IaaS). Sounds to me you are running IaaS in AWS. – Thomas Jespersen Jul 01 '15 at 21:43
  • Also... we are a startup. We work 24/7 (eg. right now it's 23:50PM in my timezone and I'm working), but sometimes a server is not used for weeks or even months. But when we need it, it should just work "right here" "right now". Maybe that's also a difference. But thanks for helping :) We solved our problem with 5 lines of C# code that will work on all Redis servers (Azure or not)... se my comment to Sunil D's answer. – Thomas Jespersen Jul 01 '15 at 21:51
  • Glad that you found a working solution. The same is on aws, we are using a service and not starting machines and install things on them, even though it's not that different because all is done using azure/aws API - you just start/stop what kind of service you need. All I was trying to say is that there are more solutions out there worth exploring, each with ups and downs. And I am sure that you picked the best for your case, so good luck dude :) – Liviu Costea Jul 02 '15 at 07:25