This article provides answers to common questions about how to manage Azure Cache for Redis.
How can I benchmark and test the performance of my cache?redis-benchmark.exe
to load test your Redis server. Use redis-benchmark.exe
to get a feel for possible throughput before writing your own performance tests.redis-cli
to monitor the cache using the INFO
command. For instructions on downloading the Redis tools, see How can I run Redis commands?--tls
parameter to your Redis tools commands, or use a proxy like stunnel
to enable TLS/SSL.Redis-benchmark
uses port 6379
by default. Use the -p
parameter to override this setting if your cache uses the SSL/TLS port 6380
or the Enterprise tier port 10000
.The following examples show how to use redis-benchmark.exe
. Run these commands from a VM in the same region as your cache for accurate results.
First, test pipelined SET
requests using a 1k payload:
redis-benchmark.exe -h <yourcache>.redis.cache.windows.net -a <yourAccesskey> -t SET -n 1000000 -d 1024 -P 50
After you run the SET
test, run pipelined GET
requests using a 1k payload:
redis-benchmark.exe -h <yourcache>.redis.cache.windows.net -a <yourAccesskey> -t GET -n 1000000 -d 1024 -P 50
Enabling server garbage collection (GC) can optimize the client and provide better performance and throughput when you use StackExchange.Redis. For more information on server GC and how to enable it, see the following articles:
Should I enable the non-TLS/SSL port for connecting to Redis?Redis server doesn't natively support Transport Layer Security (TLS), but Azure Cache for Redis does support TLS. If you connect to Azure Cache for Redis with a client like StackExchange.Redis that supports TLS, then use TLS.
Note
The non-TLS port is disabled by default for new Azure Redis instances. If your client doesn't support TLS, enable the non-TLS port by following the directions at Access ports.
If the cache uses TLS, you must enable TLS by using the --tls
option for Redis tools like redis-cli
. You can also use a utility such as stunnel
to securely connect the tools to the TLS port by following the directions in the Announcing ASP.NET Session State Provider for Redis Preview Release blog post.
For instructions on downloading the Redis tools, see How can I run Redis commands?
What are some considerations for using common Redis commands?Avoid using certain Redis commands that take a long time to complete, unless you fully understand the result of these commands. For example, don't run the KEYS command in production. Depending on the number of keys, it could take a long time to return. Redis is a single-threaded server that processes commands one at a time. If you issue the KEYS
command, Redis doesn't process subsequent commands until it finishes processing the KEYS
command.
The redis.io site has time complexity details for each operation it supports. Select each command to see the complexity for each operation.
What size keys to use depends on the scenario. If your scenario requires larger keys, you can adjust the ConnectionTimeout
, then retry values and adjust your retry logic. From a Redis server perspective, smaller key values give better performance.
These considerations don't mean that you can't store larger values in Redis, but latencies are higher. If you have one set of data that's larger than another, you can use multiple ConnectionMultiplexer
instances, each configured with a different set of timeout and retry values. For more information, see What do the StackExchange.Redis configuration options do?
Each Azure Cache for Redis pricing tier has different limits for client connections, memory, and bandwidth. While each size of cache allows up to some number of connections, each connection to Redis involves associated overhead. An example of such overhead is CPU and memory usage because of TLS/SSL encryption.
The maximum connection limit for a given cache size assumes a lightly loaded cache. If load from connection overhead plus load from client operations exceeds capacity for the system, the cache can experience capacity issues even if you don't exceed the connection limit for the current cache size.
For more information about the connection limits for each tier, see Azure Cache for Redis pricing. For more information about connections and other default configurations, see Default Redis server configuration.
What are some production best practices?AbortConnect
to false, then let the ConnectionMultiplexer
reconnect automatically.ConnectionMultiplexer
instance rather than creating a new connection for each request.connectTimeout
of 5 seconds. This interval gives StackExchange.Redis sufficient time to reestablish the connection if there's a network blip.KEYS
command is an O(n) operation and should be avoided. The redis.io site has details about the time complexity of each operation it supports. Select each command to see the complexity for each operation.The Common Language Runtime (CLR) ThreadPool has two types of threads, Worker and I/O Completion Port (IOCP).
WORKER
threads are used for things like processing the Task.Run(â¦)
, or ThreadPool.QueueUserWorkItem(â¦)
methods. Various components in the CLR also use these threads when work needs to happen on a background thread.IOCP
threads are used for asynchronous I/O, such as when reading from the network.The thread pool provides new worker threads or I/O completion threads on demand without any throttling until it reaches the minimum
setting for each type of thread. By default, the minimum number of threads is set to the number of processors on a system.
Once the number of existing busy threads hits the minimum
threads number, the ThreadPool throttles the rate at which it injects new threads to one thread per 500 milliseconds.
Typically, if your system gets a burst of work that needs an IOCP
thread, it processes that work quickly. However, if the burst is more than the configured minimum
setting, there's some delay in processing some of the work as the ThreadPool waits for one of two possibilities:
Basically, when the number of Busy
threads is greater than Min
threads, you experience a 500-ms delay before the application processes the network traffic. Also, an existing thread that stays idle for longer than 15 seconds is cleaned up, and this cycle of growth and shrinkage can repeat.
Error messages from StackExchange.Redis build 1.0.450 or later print ThreadPool statistics, as shown in the following example.
System.TimeoutException: Timeout performing GET MyKey, inst: 2, mgr: Inactive,
queue: 6, qu: 0, qs: 6, qc: 0, wr: 0, wq: 0, in: 0, ar: 0,
IOCP: (Busy=6,Free=994,Min=4,Max=1000),
WORKER: (Busy=3,Free=997,Min=4,Max=1000)
The example shows that for the IOCP
thread, there are six busy threads and the system is configured to allow four minimum threads. In this case, the client is likely to see two 500-ms delays, because 6 > 4.
Note
StackExchange.Redis can hit timeouts if growth of either IOCP
or WORKER
threads is throttled.
It's best to set the minimum configuration value for IOCP
and WORKER
threads to something larger than the default value. There's no one-size-fits-all guidance on this value, because the right value for one application is likely too high or low for another application. This setting can also affect the performance of other parts of complicated applications. You need to fine-tune this setting to your specific needs. A good starting place is 200
or 300
. Then test and tweak as needed.
You can change this setting programmatically by using the ThreadPool.SetMinThreads (...) method.
For example, in NET Framework, you set this value in Global.asax.cs in the Application_Start
method:
private readonly int minThreads = 200;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ThreadPool.SetMinThreads(minThreads, minThreads);
}
If you use .NET Core, you set the value in Program.cs just before the call to WebApplication.CreateBuilder()
:
const int minThreads = 200
ThreadPool.SetMinThreads(minThreads, minThreads);
var builder = WebApplication.CreateBuilder(args);
// rest of application setup
Note
The value specified by this method is a global setting that affects the whole AppDomain. For example, if you have a four-core VM and want to set minWorkerThreads
and minIoThreads
to 50 per CPU during runtime, use ThreadPool.SetMinThreads(200, 200)
.
It's also possible to specify the minimum threads setting by using the minIoThreads
or minWorkerThreads
configuration setting under the <processModel>
configuration element in Machine.config. Machine.config is typically located at %SystemRoot%\Microsoft.NET\Framework\<versionNumber>\CONFIG\.
Setting the number of minimum threads in this way isn't recommended because it's a system-wide setting. If you do set minimum threads this way, you must restart the application pool.
Note
The value specified by this method is a per-core setting. For example, if you have a four-core machine and want your minIoThreads
setting to be 200 at runtime, use <processModel minIoThreads="50">
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4