How to use redis in server
- Save this docker-compose.yml
- Run this command:
docker-compose up
- Launch a separate terminal to access redis-cli
docker exec -it redis bash
- Start Redis CLI
- type
redis-cli
- type
- Ping
ping
-> ResponsePONG
Commands:
set a b
- a - key
- b - value
get a
"b"
get c
(nil)
set a 1
get a
"1"
- String
set ....................bigkey............... somevalue
set 1 10
(1 is a key)set true false
Naming best practices:- API
/user/1/name
-> keyuser:1:name
- Spaces in values
set somekey some value
(error) ERR syntax error
set somekey "some value"
- Spaces in keys
set "some key" somevalue
- Keys (deprecated)
keys *
- all the keyskeys user:*
- all the keys starting with userkeys user:*:name
-
- "user:2:name"
-
- "user:1:name"
-
- `keys user:*:nan
(empty array)
- Scan (better solution)
scan 0
- all keys from page 0- it returns reference to the next page -
"6"
- it returns reference to the next page -
scan 6
- another portion of scan -
"27"
- another portion of scan -
scan 27
- back to page
"0"
- back to page
scan 0 MATCH user:*:name COUNT 5
- match pattern, limit by count, page 0
- Delete one (or list)
del key [key ...]
del user:8:name
del user:1:name user:2:name
- Delete All
flushdb
- set expiration in seconds
set a b ex 10
- 10 secondsget a
->b
-> wait for 10 secget a
->(nil)
- check TTL
set a b ex 10
- 10 secondsttl a
- extend TTL
expire a 60
- set new ttl to 60 seconds
- set expiration time at certain timestamp
set a b exat 1626465000
ttl a
-> 269
- set expiration time in millis
set a b px 30000
- change value but keep ttl
- wrong:
set a b ex 60
set a c
ttl a
-> -1 (no expiration - will keep forever)
- correct
set a b ex 60
set a c keepttl
- wrong:
- NX - Only set the key if it does not already exist.
set a b nx
(nil)
if existsOK
if not exist
- XX - Only set the key if it already exist.
set a c xx
OK
if exists(nil)
if not
exists a
-> 1exists b
-> 0set user:1:token token ex 10
exists user:1:token
- 1 (yes)
- 0 (no)
- Increment integer
set a 1
incr a
-> ++a- (integer) 2
get a
-> "2"incr non-existing-key
->(integer) 1
- Decrement integer
decr a
-> --a
- Increment float
set a 1.02
incrbyfloat a .3
-> a+=0.3- "1.32"
- Decrement float
incrbyfloat a -.3
-> a-=0.3
- Increase by certain value
incrby a 123
- Decrease by certain value
decrby a 123
- Set hash
hset key field value
hset user:1 name Art age 38 city Kramatorsk
- Type of Value by Key
type user:1
hash
- Get field value
hget user:1 name
- Get all fields
hgetall user:1
1) "name"
2) "Art"
3) "age"
4) "38"
5) "city"
6) "Kramatorsk"
- Create another object with different fields
hset user:2 name Kate birthYear 1983 status active
- Expire object
expire user:2 10
- Get all keys of hash
hkeys user:1
1) "name"
2) "age"
3) "city"
- Get all values of hash
hvals user:1
- Does field exist
hexists user:1 status
- Delete field
-
hdel user:1 age
- Delete entire object
-
del user:1
- Right-hand side push
- Insert all the specified values at the tail of the list stored at key
rpush a 1
rpush a 2 3 4 5
- Get list length
llen a
- Get elements from list
lrange a 0 3
- from index 0 to index 3 (4 total)1) "1"
2) "2"
3) "3"
4) "4"
lrange a 0 -1
- from index 0 to the endlrange a 0 1000
- from index 0 to 1000 but only existing
- Remove from list from head
lpop a
- from left remove 1 and return itlpop a 3
- from left remove 3 and return them
- Push items
rpush a 1 2 3 4 5 6
- Remove from list from tail
rpop a
- from right remove 1 and return itrpop a 3
- from right remove 3 and return them1) "5"
2) "4"
3) "3"
- OR from left-hand side
lpush a 1 2 3 4
lpop a 3
- Empty list
lpop a 1000
keys *
- (empty array) - redis deletes keys of empty list
- Add items to set
sadd users 1 2 3
- Get size of the set
scard users
- Get members
smembers users
- Check member is present
sismember users 3
- Remove item from set
srem users 5
- only member 5srem users 2 3
- 2 and 3
- Randomly pop member (and remove it from the set)
spop users
- 1 memberspop users 3
- 3 members
- Init setup
sadd skill:java 1 2 3 4
sadd skill:js 2 3 4 5
sadd skill:aws 4 5 6 7
- Intersection
sinter skill:java skill:js skill:aws
- Union
sunion skill:js skill:aws
- Difference
sadd candidate:criminal 4 5 6
sdiff skill:java candidate:criminal
- present in skill:java but absent in candidate:criminal
- Store intersection result
sinterstore java-js skill:java skill:js
- Store union result
SUNIONSTORE java-or-js skill:java skill:js
- Store diff result
SDIFFSTORE java-without-criminal skill:java candidate:criminal
- Add item
zadd products 0 books
zadd products 0 iphone 0 tv
- Get size
zcard products
- cardinality
- Increase score
zincrby key increment member
zincrby products 10 iphone
- Get sorted products
zrange products 0 -1
zrange products 0 -1 withscores
- Highest scored product
zrange products -1 -1
- OR
zrange products 0 0 rev
zrange products 0 1 rev
- top 2 products
- Rank of item
zrank products tv
- direct orderzrevrank products tv
- reverse order
- Remove items from the set
zpopmax products
- pop with max scorezpopmax products 3
- pop 3 items with max scorezpopmin products
- pop with min scorezpopmin products 3
- pop 3 items with min score
- Open 2 terminals
- Create balances for users
set user:1:balance 1
set user:2:balance 0
- Assume 2 API-clients want to transfer balance from user:1 to user:2
- term1:
get user:1:balance
-> 1 (enough) - term2:
get user:1:balance
-> 1 (enough)
- term1:
- Transfer balance by term1
127.0.0.1:6379> decr user:1:balance
(integer) 0
127.0.0.1:6379> incr user:2:balance
(integer) 1
- Transfer balance by term2
127.0.0.1:6379> decr user:1:balance
(integer) -1
127.0.0.1:6379> incr user:2:balance
(integer) 2
- INCORRECT - need a transaction
- Multi
multi
- start a transaction127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)>
(TX)
- Term1 and Term2
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decr user:1:balance
QUEUED
127.0.0.1:6379(TX)> incr user:2:balance
QUEUED
- Term1
127.0.0.1:6379(TX)> exec
1) (integer) 0
2) (integer) 1
- Term2
127.0.0.1:6379(TX)> exec
1) (integer) -1
2) (integer) 2
- does not solve our problem
- Watch key
-
watch user:1:balance user:2:balance
- Term1 and Term2
-
127.0.0.1:6379> multi
-OK
-127.0.0.1:6379(TX)> decr user:1:balance
-QUEUED
-127.0.0.1:6379(TX)> incr user:2:balance
-QUEUED
- Term1
-
127.0.0.1:6379(TX)> exec
-1) (integer) 0
-2) (integer) 1
- Term2
-127.0.0.1:6379(TX)> exec
-(nil)
- After
exec
redis will remove watch - Discard transaction - Rollback
-
127.0.0.1:6379> multi
-OK
-127.0.0.1:6379(TX)> incr user:2:balance
-QUEUED
-127.0.0.1:6379(TX)> decr user:1:balance
-QUEUED
-127.0.0.1:6379(TX)> discard
-OK
-127.0.0.1:6379>
- Working dir
/data
- in Docker container- may be empty
- I have file
dump.rdb
REDIS0009� redis-ver�6.2.4�
redis-bits�@��ctime��%�
��used-mem � �aof-preamble� ���-/=}ւ`
- Redis periodically saves data
- Enforce saving process
bgsave
- Background saving
Before and after implementing String Serializer
127.0.0.1:6379> get user:1:name
"\x04>\x03Art"
127.0.0.1:6379> get user:1:name
"Art"
- With Serializable
127.0.0.1:6379> get student:1
"\x04\x04\t>2net.shyshkin.study.redis.redisson.test.dto.Student\xa10E\xa5h\x85\x10C\x00\x00\x00\x03>\x03age#\x00>\x04city\x16\x00>\x04name\x16\x00\x16\x00\x00\x00\x17>\x0bAmeliamouth>\rBreana Kohler"
- With JsonJacksonCodec and class name
127.0.0.1:6379> get student:1
"{\"@class\":\"net.shyshkin.study.redis.redisson.test.dto.Student\",\"age\":20,\"city\":\"Kunzeshire\",\"name\":\"Saran Mayer\"}"
- With JsonJacksonCodec and without class name
127.0.0.1:6379> get student:1
"{\"age\":19,\"city\":\"Treutelport\",\"marks\":[5,6,12],\"name\":\"Cindy Koss\"}"
- Enable notification via configuration
- method 1 (redis cli):
config set notify-keyspace-events AKE
- method 2 (
redis.conf
- bind mount) - method 3 (own Dockerfile for own image with COPY option (immutable))
- Test if server is running
telnet localhost 6379
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
- Test pipeline
- Start
docker-compose
- Run
server1
- View name
Art
- View name
- Run
server2
- View name
Art-updated
- View name
- Down
docker-compose
(stop Redis server)- View server2 logs continue emitting cached data
telnet localhost 6379
(in ubuntu)Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
- Up Redis server again
- Run server3
- All the data for server1 should change
- Start
- Test pipeline
- Start
docker-compose
- Run
server1
- View name
Art
- View name
- Run
server2
- View name in server1 still
Art
- NO UPDATE HAPPENED
- View name in server1 still
- View in redis-cli
hgetall students
- View
Art-updated
- Start
- Test pipeline
- Start
docker-compose
- Run
server1
- View name
Art
- View name
- Run
server2
- View name in server1 still
Art
- NO UPDATE HAPPENED
- View name in server1 still
- View in redis-cli
hgetall students
- View
Art-updated
- Stop redis server
- Restart redis server
- In server1 - Student is null
- Run server3
- In server1 Updated all the fields
- Start
- Start subscribers
- Publish through code by
topic.publish
- Publish through
redis-cli
publish slack-room hi
publish slack-room "how are you"
Start service in Java VM
java -jar city-api.jar
http://localhost:3030/open-city-api/{zipcode}
zipcode
from us.jsonhttp://localhost:3030/open-city-api/00603
Create Docker image
docker build -t artarkatesoft/art-vinsguru-city-api:latest .
docker push artarkatesoft/art-vinsguru-city-api
- Download JMeter
- Download product-service.jmx
- Run
<jmeter_dir>/bin/jmeter.bat
(for Windows)
Don't use GUI mode for load testing !, only for Test creation and Test debugging.
For load testing, use CLI Mode (was NON GUI):
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
- Open
product-service.jmx
- Disable
View Results Tree
- Run Tests for 60 seconds for Warm Up Server
- Modify Tests to run for 300 seconds
- Save and close
- Start Test
jmeter.bat -n -t product-service.jmx -l results/v1.jtl
- or
run_test.bat
- When test finished open result in GUI
jmeter.bat
- Test Plan -> (RightMouseClick / Edit) -> Add -> Listener -> Aggregate Report ->
Write results to file / Read from file
-> Browse -> v1.jtl
- Package project
mvn clean package -DskipTests
- Start instance 1
java -jar ./target/redis-performance-0.0.1-SNAPSHOT.jar
- Start instance 2
java -jar ./target/redis-performance-0.0.1-SNAPSHOT.jar --server.port=8081
- or by configuring IntelliJ IDEA
- Copy configuration from RedisPerformanceApplication
- Program Arguments:
--server.port=8081
- Smart Websocket Client (Chrome plugin)
acl list
- show current users1) "user default on nopass ~* &* +@all"
acl whoami
- current user"default"
acl setuser [username]>[password]
- creates a user with a password- space before secret is not allowed
127.0.0.1:6379> acl setuser art > secret
(error) ERR Error in ACL SETUSER modifier 'secret': Syntax error
127.0.0.1:6379> acl setuser art >secret
OK
acl list
1) "user art off #2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b &* -@all"
2) "user default on nopass ~* &* +@all"
- by default new user is not enabled
acl deluser art
acl setuser art >pass123 on
- enabled
- space before secret is not allowed
acl setuser [username] nopass
- creates a user with no passwordacl setuser [username] on
- enables the useracl setuser [username] off
- disables the useracl setuser art off
acl deluser [username]
- removes the user- Authenticate
auth art pass123
OK
127.0.0.1:6379> acl whoami
(error) NOPERM this user has no permissions to run the 'acl' command or its subcommand
- art has NO permissions yet
auth default nopass
- log in as default user
command | description |
---|---|
allcommands / +@all |
access to all the commands in redis |
-get,-set... |
no access to get/set commands |
+@set, +@hash, +@list |
access set and hash related commands |
allkeys / ~* |
access to the keys in redis |
~numbers:* |
access to the keys starting with numbers: |
acl setuser art >pass123 on allcommands allkeys
127.0.0.1:6379> acl list
1) "user art on #9b8769a4a742959a2d0298c36fb70623f2dfacda8436237df08d8dfd5b37374c ~* &* +@all"
2) "user default on nopass ~* &* +@all"
auth art pass123
acl list
- art:
user art on #9b8769a4a742959a2d0298c36fb70623f2dfacda8436237df08d8dfd5b37374c ~* &* +@all
acl setuser art -set
user art on #9b8769a4a742959a2d0298c36fb70623f2dfacda8436237df08d8dfd5b37374c ~* &* +@all -set"
set a b
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
rpush users 1 2 3
-> (integer) 3
- art:
acl setuser art -@dangerous
flushdb
->(error) NOPERM this user has no permissions to run the 'flushdb' command or its subcommand
config set requirepass pass98765
auth default nopass
(error) WRONGPASS invalid username-password pair or user is disabled.
- exit redis-cli and reenter it
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
auth default pass98765
- to come back to default behaviour:
config set requirepass ""
- Set default user password
config set requirepass pass98765
- Create user art
acl setuser art >pass123 on allcommands allkeys -@dangerous