Using ServiceStack, is there a way to perform multiple read commands (in particular the ContainsKey command)?
The objects stored take a while to fetch from the database, so we're looking to get only the ones that are not in cache.
I know that I can ask redis for the object and then fetch from the database if it comes back null, but the objects being stored are fairly large, so I'd rather just get a list of bools back and then determine which ids to query in the database from that.
For the time being I'm looping through my list of Ids (can be up to 100 or so) and using the ContainsKey method in servicestack. I'm looking to avoid all of the back and forth and make all of the requests in one shot.
On the ServiceStack.Redis client you can use GetValues
or GetValuesMap
(both string and T apis are available) for fetching multiple values (uses MGET) in a single call. Only existing items are returned, which you can detect with GetValues
if you have Id's on your models or GetValuesMap
which returns a dictionary of existing keys and their values.
From this, you can determine and fetch all the missing Ids from the database. If you're just going to fetch the existing values from Redis anyway, then this is the most optimal strategy since you can fetch all the values and determine the existing keys with 1 call.
Alternative 'Single Call' options
Use Pipelining or Transactions
If for some reason you really only want to check the existence of keys in Redis without fetching them, then you can use a Transaction / or Pipeline (both are pipelined) to queue up multiple operations that gets sent to Redis in 1 socket write. Here's an example of this from RedisStackOverflow demo that queues up 30 operations that gets send and executed in a single batch.
Use LUA Scripting
If you have Redis >v2.5x you can create and execute composite operations using Redis's server-side LUA support. You can use these APIs from IRedisClient in ServiceStack.Redis client to execute server-side LUA scripts:
string GetEvalStr(string body, int numOfArgs, params string[] args);
int GetEvalInt(string body, int numOfArgs, params string[] args);
List<string> GetEvalMultiData(string body, int numOfArgs, params string[] args);