1- # NebulexRedisAdapter
1+ # Nebulex.Adapters.Redis
22> Nebulex adapter for Redis (including [ Redis Cluster] [ redis_cluster ] support).
33
44![ CI] ( https://github.com/cabol/nebulex_redis_adapter/workflows/CI/badge.svg )
@@ -15,7 +15,7 @@ next sections.
1515See also [ online documentation] [ nbx_redis_adapter ]
1616and [ Redis cache example] [ nbx_redis_example ] .
1717
18- [ nbx_redis_adapter ] : http://hexdocs.pm/nebulex_redis_adapter/NebulexRedisAdapter .html
18+ [ nbx_redis_adapter ] : http://hexdocs.pm/nebulex_redis_adapter/Nebulex.Adapters.Redis .html
1919[ nbx_redis_example ] : https://github.com/cabol/nebulex_examples/tree/master/redis_cache
2020[ redis_cluster ] : https://redis.io/topics/cluster-tutorial
2121
@@ -26,9 +26,9 @@ Add `:nebulex_redis_adapter` to your list of dependencies in `mix.exs`:
2626``` elixir
2727defp deps do
2828 [
29- {:nebulex_redis_adapter , " ~> 2.3 " },
30- {:crc , " ~> 0.10" }, # => Needed when using Redis Cluster
31- {:jchash , " ~> 0.1.4 " } # => Needed when using consistent-hashing
29+ {:nebulex_redis_adapter , " ~> 3.0 " },
30+ {:crc , " ~> 0.10" }, # => Needed when using `:redis_cluster` mode
31+ {:ex_hash_ring , " ~> 6.0 " } # => Needed when using `:client_side_cluster` mode
3232 ]
3333end
3434```
@@ -38,8 +38,8 @@ needed ones. For example:
3838
3939 * ` :crc ` - Required when using the adapter in mode ` :redis_cluster ` .
4040 See [ Redis Cluster] [ redis_cluster ] .
41- * ` :jchash ` - Required if you want to use consistent-hashing when using the
42- adapter in mode ` :client_side_cluster ` .
41+ * ` :ex_hash_ring ` - Required when using the adapter in mode
42+ ` :client_side_cluster ` .
4343
4444Then run ` mix deps.get ` to fetch the dependencies.
4545
@@ -51,7 +51,7 @@ After installing, we can define our cache to use Redis adapter as follows:
5151defmodule MyApp .RedisCache do
5252 use Nebulex .Cache ,
5353 otp_app: :my_app ,
54- adapter: NebulexRedisAdapter
54+ adapter: Nebulex . Adapters . Redis
5555end
5656```
5757
@@ -69,15 +69,15 @@ config :my_app, MyApp.RedisCache,
6969
7070Since this adapter is implemented by means of ` Redix ` , it inherits the same
7171options, including regular Redis options and connection options as well. For
72- more information about the options, please check out ` NebulexRedisAdapter `
72+ more information about the options, please check out ` Nebulex.Adapters.Redis `
7373module and also [ Redix] ( https://github.com/whatyouhide/redix ) .
7474
7575See also [ Redis cache example] [ nbx_redis_example ] .
7676
7777## Distributed Caching
7878
7979There are different ways to support distributed caching when using
80- ** NebulexRedisAdapter ** .
80+ ** Nebulex.Adapters.Redis ** .
8181
8282### Redis Cluster
8383
@@ -95,7 +95,7 @@ Then we can define our cache which will use **Redis Cluster**:
9595defmodule MyApp .RedisClusterCache do
9696 use Nebulex .Cache ,
9797 otp_app: :my_app ,
98- adapter: NebulexRedisAdapter
98+ adapter: Nebulex . Adapters . Redis
9999end
100100```
101101
@@ -127,20 +127,20 @@ The pool of connections to the different master nodes is automatically
127127configured by the adapter once it gets the cluster slots info.
128128
129129> This one could be the easiest and recommended way for distributed caching
130- using Redis and ** NebulexRedisAdapter ** .
130+ using Redis and ** Nebulex.Adapters.Redis ** .
131131
132- ### Client-side Cluster based on Sharding
132+ ### Client-side Cluster
133133
134- ** NebulexRedisAdapter ** also brings with a simple client-side cluster
135- implementation based on Sharding distribution model.
134+ ** Nebulex.Adapters.Redis ** also brings with a simple client-side cluster
135+ implementation based on sharding distribution model.
136136
137137We define our cache normally:
138138
139139``` elixir
140140defmodule MyApp .ClusteredCache do
141141 use Nebulex .Cache ,
142142 otp_app: :my_app ,
143- adapter: NebulexRedisAdapter
143+ adapter: Nebulex . Adapters . Redis
144144end
145145```
146146
@@ -182,101 +182,41 @@ config :my_app, MyApp.ClusteredCache,
182182 ]
183183```
184184
185- By default, the adapter uses ` NebulexRedisAdapter.ClientCluster.Keyslot ` for the
186- keyslot. Besides, if ` :jchash ` is defined as dependency, the adapter will use
187- consistent-hashing automatically.
188-
189- > ** NOTE:** It is highly recommended to define the ` :jchash ` dependency
190- when using the adapter in ` :client_side_cluster ` mode.
191-
192- However, you can also provide your own implementation by implementing the
193- ` Nebulex.Adapter.Keyslot ` and set it into the ` :keyslot ` option. For example:
194-
195- ``` elixir
196- defmodule MyApp .ClusteredCache .Keyslot do
197- use Nebulex .Adapter .Keyslot
198-
199- @impl true
200- def hash_slot (key, range) do
201- # your implementation goes here
202- end
203- end
204- ```
205-
206- And the config:
207-
208- ``` elixir
209- config :my_app , MyApp .ClusteredCache ,
210- # Enable client-side cluster mode
211- mode: :client_side_cluster ,
212-
213- client_side_cluster: [
214- # Provided Keyslot implementation
215- keyslot: MyApp .ClusteredCache .Keyslot ,
216-
217- # Nodes config (each node has its own options)
218- nodes: [
219- .. .
220- ]
221- ]
222- ```
223-
224- ### Using ` Nebulex.Adapters.Partitioned `
225-
226- Another simple option is to use the ` Nebulex.Adapters.Partitioned ` and set as
227- local cache the ` NebulexRedisAdapter ` . The idea here is each Elixir node running
228- the distributed cache (` Nebulex.Adapters.Partitioned ` ) will have as local
229- backend or cache a Redis instance (handled by ` NebulexRedisAdapter ` ).
230-
231-
232- This example shows how the setup a distributed cache using
233- ` Nebulex.Adapters.Partitioned ` and ` NebulexRedisAdapter ` :
234-
235- ``` elixir
236- defmodule MyApp .DistributedCache do
237- use Nebulex .Cache ,
238- otp_app: :my_app ,
239- adapter: Nebulex .Adapters .Partitioned ,
240- primary_storage_adapter: NebulexRedisAdapter
241- end
242- ```
243-
244185### Using a Redis Proxy
245186
246187The other option is to use a proxy, like [ Envoy proxy] [ envoy ] or
247188[ Twemproxy] [ twemproxy ] on top of Redis. In this case, the proxy does the
248- distribution work, and from the adparter's side (** NebulexRedisAdapter ** ),
189+ distribution work, and from the adparter's side (** Nebulex.Adapters.Redis ** ),
249190it would be only configuration. Instead of connect the adapter against the
250191Redis nodes, we connect it against the proxy nodes, this means, in the config,
251192we setup the pool with the host and port pointing to the proxy.
252193
253194[ envoy ] : https://www.envoyproxy.io/
254195[ twemproxy ] : https://github.com/twitter/twemproxy
255196
256- ## Running Redis commands and/or pipelines
197+ ## Using the adapter as a Redis client
257198
258- Since ` NebulexRedisAdapter ` works on top of ` Redix ` and provides features like
259- connection pools and "Redis Cluster" support, it may be seen also as a sort of
260- Redis client, but it is meant to be used mainly with the Nebulex cache API.
261- However, Redis API is quite extensive and there are a lot of useful commands
262- we may want to run taking advantage of the ` NebulexRedisAdapter ` features.
263- Therefore, the adapter injects two additional/extended functions to the
264- defined cache: ` command!/2 ` and ` pipeline!/2 ` .
199+ Since the Redis adapter works on top of ` Redix ` and provides features like
200+ connection pools, "Redis Cluster", etc., it may also work as a Redis client.
201+ The Redis API is quite extensive, and there are many useful commands we may
202+ want to run, leveraging the Redis adapter features. Therefore, the adapter
203+ provides additional functions to do so.
265204
266205``` elixir
267- iex> MyCache .command! ([" LPUSH" , " mylist" , " world" ], key: " mylist" )
206+ iex> conn = MyCache .fetch_conn! ()
207+ iex> Redix .command! (conn, [" LPUSH" , " mylist" , " world" ])
2682081
269- iex> MyCache .command! ([" LPUSH" , " mylist" , " hello" ], key: " mylist " )
209+ iex> Redix .command! (conn, [" LPUSH" , " mylist" , " hello" ])
2702102
271- iex> MyCache .command! ([" LRANGE" , " mylist" , " 0" , " -1" ], key: " mylist " )
211+ iex> Redix .command! (conn, [" LRANGE" , " mylist" , " 0" , " -1" ])
272212[" hello" , " world" ]
273213
274- iex> [
214+ iex> conn = MyCache .fetch_conn! (key: " mylist" )
215+ iex> Redix .pipeline! (conn, [
275216.. .> [" LPUSH" , " mylist" , " world" ],
276217.. .> [" LPUSH" , " mylist" , " hello" ],
277218.. .> [" LRANGE" , " mylist" , " 0" , " -1" ]
278- .. .> ]
279- .. .> |> cache .pipeline! (key: " mylist" )
219+ .. .> ])
280220[1 , 2 , [" hello" , " world" ]]
281221```
282222
@@ -287,8 +227,8 @@ you have to pass the cache name explicitly.
287227
288228## Testing
289229
290- To run the ** NebulexRedisAdapter ** tests you will have to have Redis running
291- locally. ** NebulexRedisAdapter ** requires a complex setup for running tests
230+ To run the ** Nebulex.Adapters.Redis ** tests you will have to have Redis running
231+ locally. ** Nebulex.Adapters.Redis ** requires a complex setup for running tests
292232(since it needs a few instances running, for standalone, cluster and Redis
293233Cluster). For this reason, there is a [ docker-compose.yml] ( docker-compose.yml )
294234file in the repo so that you can use [ Docker] [ docker ] and
@@ -302,7 +242,7 @@ $ docker-compose up
302242[ docker ] : https://www.docker.com/
303243[ docker_compose ] : https://docs.docker.com/compose/
304244
305- Since ` NebulexRedisAdapter ` uses the support modules and shared tests
245+ Since ` Nebulex.Adapters.Redis ` uses the support modules and shared tests
306246from ` Nebulex ` and by default its test folder is not included in the Hex
307247dependency, the following steps are required for running the tests.
308248
@@ -373,4 +313,4 @@ all checks run successfully.
373313
374314Copyright (c) 2018, Carlos Bolaños.
375315
376- NebulexRedisAdapter source code is licensed under the [ MIT License] ( LICENSE ) .
316+ Nebulex.Adapters.Redis source code is licensed under the [ MIT License] ( LICENSE ) .
0 commit comments