From a3ca576df9179040076da42ad006f6b8ad22dc38 Mon Sep 17 00:00:00 2001 From: William Johnston Date: Wed, 30 Aug 2023 13:34:37 -0700 Subject: [PATCH] removing lettuce from antipatterns --- .../redisinsight/streams/index-streams.mdx | 2 +- .../antipatterns/index-antipatterns.mdx | 47 ++++--------------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/docs/explore/redisinsight/streams/index-streams.mdx b/docs/explore/redisinsight/streams/index-streams.mdx index 486c9d6d5a0..758b5592add 100644 --- a/docs/explore/redisinsight/streams/index-streams.mdx +++ b/docs/explore/redisinsight/streams/index-streams.mdx @@ -20,7 +20,7 @@ Redis Streams lets you build “Kafka-like” applications, which can: In addition, Redis Streams has the concept of a consumer group. Redis Streams consumer groups, like the similar concept in [Apache Kafka](https://kafka.apache.org/), allows client applications to consume messages in a distributed fashion (multiple clients), making it easy to scale and create highly available systems. -Let’s dive under the covers and see [Redis Streams](https://redis.io/topics/streams-intro) through the lens of RedisInsight. You will see how to use the [Lettuce Java client](https://developer.redis.com/develop/java/#using-lettuce) to publish and consume messages using consumer group.This is the first basic example that uses a single consumer. +Let’s dive under the covers and see [Redis Streams](https://redis.io/topics/streams-intro) through the lens of RedisInsight. You will see how to use the Redis to publish and consume messages using a consumer group. This is the first basic example that uses a single consumer. ## Prerequisite: diff --git a/docs/howtos/antipatterns/index-antipatterns.mdx b/docs/howtos/antipatterns/index-antipatterns.mdx index 715d1c8abc6..e3956ad7507 100644 --- a/docs/howtos/antipatterns/index-antipatterns.mdx +++ b/docs/howtos/antipatterns/index-antipatterns.mdx @@ -39,60 +39,33 @@ Let us look at the redis-py that uses a connection pool to manage connections to [Learn more about redis-py](/develop/python/) -### Example #2 - Lettuce - -Lettuce provides generic connection pool support.Lettuce connections are designed to be thread-safe so one connection can be shared amongst multiple threads and Lettuce connections auto-reconnection by default. While connection pooling is not necessary in most cases it can be helpful in certain use cases. Lettuce provides generic connection pooling support. - -```java - RedisClient client = RedisClient.create(RedisURI.create(host, port)); - - GenericObjectPool> pool = ConnectionPoolSupport - .createGenericObjectPool(() -> client.connect(), new GenericObjectPoolConfig()); - - // executing work - try (StatefulRedisConnection connection = pool.borrowObject()) { - - RedisCommands commands = connection.sync(); - commands.multi(); - commands.set("key", "value"); - commands.set("key2", "value2"); - commands.exec(); - } - - // terminating - pool.close(); - client.shutdown(); -``` - -[Learn more about Lettuce](/develop/java/?s=lettuce) - -### 3. Connecting directly to Redis instances +### 2. Connecting directly to Redis instances With a large number of clients, a reconnect flood will be able to simply overwhelm a single threaded Redis process and force a failover. Hence, it is recommended that you should use the right tool that allows you to reduce the number of open connections to your Redis server. [Redis Enterprise DMC proxy](https://docs.redis.com/latest/rs/administering/designing-production/networking/multiple-active-proxy/) allows you to reduce the number of connections to your cache server by acting as a proxy. There are other 3rd party tool like [Twemproxy](https://github.com/twitter/twemproxy). It is a fast and lightweight proxy server that allows you to reduce the number of open connections to your Redis server. It was built primarily to reduce the number of connections to the caching servers on the backend. This, together with protocol pipelining and sharding enables you to horizontally scale your distributed caching architecture. -### 4. More than one secondary shard (Redis OSS) +### 3. More than one secondary shard (Redis OSS) Redis OSS uses a shard-based quorum. It's advised to use at least 3 copies of the data (2 replica shards per master shard) in order to be protected from split-brain situations. In nutshell, Redis OSS solves the quorum challenge by having an odd number of shards (primary + 2 replicas). Redis Enterprise solves the quorum challenge with an odd number of nodes. Redis Enterprise avoids a split-brain situation with only 2 copies of the data, which is more cost-efficient. In addition, the so-called ‘quorum-only node' can be used to bring a cluster up to an odd number of nodes if an additional, not necessary data node would be too expensive. -### 5. Performing single operation +### 4. Performing single operation Performing several operations serially increases connection overhead. Instead, use [Redis Pipelining](https://redis.io/topics/pipelining). Pipelining is the process of sending multiple messages down the pipe without waiting on the reply from each - and (typically) processing the replies later when they come in. Pipelining is completely a client side implementation. It is aimed at solving response latency issues in high network latency environments. So, the lesser the amount of time spent over the network in sending commands and reading responses, the better. This is effectively achieved by buffering. The client may (or may not) buffer the commands at the TCP stack (as mentioned in other answers) before they are sent to the server. Once they are sent to the server, the server executes them and buffers them on the server side. The benefit of the pipelining is a drastically improved protocol performance. The speedup gained by pipelining ranges from a factor of five for connections to localhost up to a factor of at least one hundred over slower internet connections. -### 6. Caching keys without TTL +### 5. Caching keys without TTL Redis functions primarily as a key-value store. It is possible to set timeout values on these keys. Said that, a timeout expiration automatically deletes the key. Additionally, when we use commands that delete or overwrite the contents of the key, it will clear the timeout. Redis TTL command is used to get the remaining time of the key expiry in seconds. TTL returns the remaining time to live of a key that has a timeout. This introspection capability allows a Redis client to check how many seconds a given key will continue to be part of the dataset.Keys will accumulate and end up being evicted. Hence, it is recommended to set TTLs on all caching keys. -### 7. Endless Redis Replication Loop +### 6. Endless Redis Replication Loop When attempting to replicate a very large active database over a slow or saturated link, replication never finishes due to the continuous updates. Hence, it is recommended to tune the slave and client buffers to allow for slower replication. Check out [this detailed blog](https://redis.com/blog/the-endless-redis-replication-loop-what-why-and-how-to-solve-it/). -### 8. Hot Keys +### 7. Hot Keys Redis can easily become the core of your app’s operational data, holding valuable and frequently accessed information. However, if you centralize the access down to a few pieces of data accessed constantly, you create what is known as a hot-key problem. In a Redis cluster, the key is actually what determines where in the cluster that data is stored. The data is stored in one single, primary location based off of hashing that key. So, when you access a single key over and over again, you’re actually accessing a single node/shard over and over again. Let’s put it another way—if you have a cluster of 99 nodes and you have a single key that gets a million requests in a second, all million of those requests will be going to a single node, not spread across the other 98 nodes. @@ -104,7 +77,7 @@ Redis even provides tools to find where your hot keys are located. Use redis-cli When possible, the best defence is to avoid the development pattern that is creating the situation. Writing the data to multiple keys that reside in different shards will allow you to access the same data more frequently. In nutshell, having specific keys that are accessed with every client operation. Hence, it's recommended to shard out hot keys using hashing algorithms. You can set policy to LFU and run redis-cli --hotkeys to determine. -### 9. Using Keys command +### 8. Using Keys command In Redis, the KEYS command can be used to perform exhaustive pattern matching on all stored keys. This is not advisable, as running this on an instance with a large number of keys could take a long time to complete, and will slow down the Redis instance in the process. In the relational world, this is equivalent to running an unbound query (SELECT...FROM without a WHERE clause). Execute this type of operation with care, and take necessary measures to ensure that your tenants are not performing a KEYS operation from within their application code. Use SCAN, which spreads the iteration over many calls, not tying up your whole server at one time. @@ -115,17 +88,17 @@ Scaning keyspace by keyname is an extremely slow operation and will run O(N) wit 2SQL: SELECT * FROM orders WHERE make=ford AND model=explorer" ``` -### 10. Running Ephemeral Redis as a primary database +### 9. Running Ephemeral Redis as a primary database Redis is often used as a primary storage engine for applications. Unlike using Redis as a cache, using Redis as a primary database requires two extra features to be effective. Any primary database should really be highly available. If a cache goes down, then generally your application is in a brown-out state. If a primary database goes down, your application also goes down. Similarly, if a cache goes down and you restart it empty, that’s no big deal. For a primary database, though, that’s a huge deal. Redis can handle these situations easily, but they generally require a different configuration than running as a cache. Redis as a primary database is great, but you’ve got to support it by turning on the right features. With Redis open source, you need to set up Redis Sentinel for high availability. In Redis Enterprise, it’s a core feature that you just need to turn on when creating the database. As for durability, both Redis Enterprise and open source Redis provide durability through AOF or snapshotting so your instance(s) start back up the way you left them. -### 11. Storing JSON blobs in a string +### 10. Storing JSON blobs in a string Microservices written in several languages may not marshal/unmarshal JSON in a consistent manner. Application logic will be required to lock/watch a key for atomic updates. JSON manipulation is often a very compute costly operation. Hence, it is recommended to use HASH data structure and also Redis JSON. -### 12. Translating a table or JSON to a HASH without considering query pattern +### 11. Translating a table or JSON to a HASH without considering query pattern The only query mechanism is a SCAN which requires reading the data structure and limits filtering to the MATCH directive. It is recommended to store the table or JSON as a string. Break out the indexes into reverse indexes using a SET or SORTED SET and point back to the key for the string. Using SELECT command and multiple databases inside one Redis instance