How does ServiceStack Redis function in retrieving

2019-07-30 02:32发布

问题:

Not sure if it's the best title for the question... maybe someone could rename it for me?

My question is regarding performance of reading and combining data in c# ServiceStack wrapper for Redis and how the calls work internally.

I will explain two scenarios that will hopefully yield in a final result. One scenario has the list of category id's attached to the Transaction so that the Category can be stored independently.

Question: My end goal is to retrieve all transactions that have category 'food'.

I have tried to number other points where clarity would help my understanding. Consider there being 10,000 transactions and each transaction had on average 3 categories.

Note: There is a related question at ServiceStack.Net Redis: Storing Related Objects vs. Related Object Ids however doesn't explain the efficiency.

Example A

public class Transaction
{
    public List<string> CategoryIds;
}

Example B

public class Transaction
{
    public List<string> CategoryNames;
}

Code

var transactionClient = redisClient.GetTypedClient<Transaction>();

//1. is this inefficient returning all transactions?
//   is there any filtering available at this part?
var allTransactions = transactionClient.GetAll();

//2. In the case of Example A where the categories are stored as id's
//   how would I map the categories to a transaction?
//   maybe I have a List that has a container with the Transaction associated with a
//   list of Categories, however this seems inefficient as I would have to loop 
//   through all transactions make a call to get their Categories and then 
//   populate the container datatype.

//3. If we are taking Example B how can I efficiently just retrieve the transactions
//   where they have a category of food.

回答1:

The efficiency is less network calls vs more data. Data in Redis just gets blobbed, most of the time a single API call maps 1:1 with a redis server operation. Which means you can think about the perf implications as simply downloading a json dataset blob from a remote server's memory and deserializing it on the client - which is effectively all that happens.

In some APIs such as GetAll() it requires 2 calls, 1 to fetch all the ids in the Entity set, and the other to fetch all the records with those ids. The source code of the Redis Client is quite approachable so I recommend having a look to see exactly what's happening.

Because you've only got 3 categories, it's not that much extra data you're saving by trying to filter on the server.

So your options are basically:

  • Download the entire entity dataset and filter on the client
  • Maintain a custom index mapping from Category > Ids
  • More Advanced: Use a server-side LUA operation to apply server side filtering (requires Redis 2.6)