東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

简单学习Redis

2022年6月29日星期三



Redis是一种数据库。

单机数据库 -> Memcached缓存 -> 读写分离 -> 分库分表(集群) ->NoSQL。

缓存、水平拆分。

读写分离,一部分库用来写,一部分库用来读。

分库分表,垂直拆分,一张表拆分多张表或多个库,如按天建表建库。

Not Only SQL。非关系型数据库。

关系型数据库用表存储。

非关系型数据库,改变底层存储机制,不再采用关系数据模型,而是采用聚合数据结构存储数据。

如 Redis、MongoDB、HBASE等。

Remote Dictionary Server 远程字典服务器 Redis。

特点:支持数据持久化、支持多种数据结构、支持数据备份。

1,安装Redis

https://redis.io/

[senrsl@localhost redis-5.0.14]$ sudo yum install gcc

[senrsl@localhost redis-5.0.14]$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
目标:x86_64-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
线程模型:posix
gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
[senrsl@localhost redis-5.0.14]

清理并重新编译

[senrsl@localhost redis-5.0.14]$ make distclean
cd src && make distclean
make[1]: 进入目录“/home/senrsl/redis/redis-5.0.14/src”
rm -rf redis-server redis-sentinel redis-cli redis-benchmark redis-check-rdb redis-check-aof *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep dict-benchmark
(cd ../deps && make distclean)
make[2]: 进入目录“/home/senrsl/redis/redis-5.0.14/deps”
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
make[2]: 离开目录“/home/senrsl/redis/redis-5.0.14/deps”
(rm -f .make-*)
make[1]: 离开目录“/home/senrsl/redis/redis-5.0.14/src”
[senrsl@localhost redis-5.0.14]$ make

[senrsl@localhost redis-5.0.14]$ sudo make install
[sudo] senrsl 的密码:
cd src && make install
make[1]: 进入目录“/home/senrsl/redis/redis-5.0.14/src”

Hint: It's a good idea to run 'make test' ;)

    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
make[1]: 离开目录“/home/senrsl/redis/redis-5.0.14/src”
[senrsl@localhost redis-5.0.14]$


2,启动

[senrsl@localhost redis-5.0.14]$ redis-server &
[1] 25071
[senrsl@localhost redis-5.0.14]$ 25071:C 11 Jun 2022 22:59:22.604 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
25071:C 11 Jun 2022 22:59:22.604 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=25071, just started
25071:C 11 Jun 2022 22:59:22.604 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
25071:M 11 Jun 2022 22:59:22.605 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
25071:M 11 Jun 2022 22:59:22.605 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
25071:M 11 Jun 2022 22:59:22.605 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._                                                 
           _.-``__ ''-._                                            
      _.-``    `.  `_.  ''-._           Redis 5.0.14 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 25071
  `-._    `-._  `-./  _.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |           http://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |                                 
  `-._    `-._`-.__.-'_.-'    _.-'                                  
      `-._    `-.__.-'    _.-'                                      
          `-._        _.-'                                          
              `-.__.-'                                              

25071:M 11 Jun 2022 22:59:22.607 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
25071:M 11 Jun 2022 22:59:22.607 # Server initialized
25071:M 11 Jun 2022 22:59:22.607 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
25071:M 11 Jun 2022 22:59:22.607 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
25071:M 11 Jun 2022 22:59:22.607 * Ready to accept connections

确认启动

[senrsl@localhost redis-5.0.14]$ ps -ef | grep redis
senrsl    25071  17943  0 22:59 pts/0    00:00:00 redis-server *:6379
senrsl    25081  17943  0 23:00 pts/0    00:00:00 grep --color=auto redis
[senrsl@localhost redis-5.0.14]$


3,关闭

[senrsl@localhost redis-5.0.14]$ redis-cli shutdown
25071:M 11 Jun 2022 23:10:42.775 # User requested shutdown...
25071:M 11 Jun 2022 23:10:42.775 * Saving the final RDB snapshot before exiting.
25071:M 11 Jun 2022 23:10:42.776 * DB saved on disk
25071:M 11 Jun 2022 23:10:42.776 # Redis is now ready to exit, bye bye...
[1]+  完成                  redis-server
[senrsl@localhost redis-5.0.14]$

4,默认客户端操作

[senrsl@localhost redis-5.0.14]$ redis-cli
127.0.0.1:6379>

//指定机器IP和端口

[senrsl@localhost redis-5.0.14]$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>

[senrsl@localhost redis-5.0.14]$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> exit
[senrsl@localhost redis-5.0.14]$ redis-cli
127.0.0.1:6379> quit
[senrsl@localhost redis-5.0.14]$

5,性能测试

[senrsl@localhost redis-5.0.14]$ redis-benchmark
====== PING_INLINE ======
  100000 requests completed in 1.72 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

95.98% <= 1 milliseconds
99.72% <= 2 milliseconds
99.81% <= 3 milliseconds
99.89% <= 4 milliseconds
99.90% <= 6 milliseconds
99.95% <= 7 milliseconds
99.99% <= 8 milliseconds
100.00% <= 8 milliseconds
58241.12 requests per second

。。。。

6,是否正常运行

[senrsl@localhost redis-5.0.14]$ redis-cli
127.0.0.1:6379> ping
PONG //正常
127.0.0.1:6379>

7,统计信息

127.0.0.1:6379> info
# Server
redis_version:5.0.14
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:a97cf54fb51d1c92
redis_mode:standalone
os:Linux 3.10.0-1160.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:25251
run_id:79159e82d8b7702b106e30c2ebebb6f68eb84c7d
tcp_port:6379
uptime_in_seconds:716
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:10794193
executable:/home/senrsl/redis/redis-5.0.14/redis-server
config_file:

# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

# Memory
used_memory:1079024
used_memory_human:1.03M
used_memory_rss:4689920
used_memory_rss_human:4.47M
used_memory_peak:4602168
used_memory_peak_human:4.39M
used_memory_peak_perc:23.45%
used_memory_overhead:562678
used_memory_startup:512792
used_memory_dataset:516346
used_memory_dataset_perc:91.19%
allocator_allocated:1511120
allocator_active:1925120
allocator_resident:8814592
total_system_memory:1019572224
total_system_memory_human:972.34M
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.27
allocator_frag_bytes:414000
allocator_rss_ratio:4.58
allocator_rss_bytes:6889472
rss_overhead_ratio:0.53
rss_overhead_bytes:-4124672
mem_fragmentation_ratio:4.52
mem_fragmentation_bytes:3652896
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1654961074
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:368640
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

# Stats
total_connections_received:954
total_commands_processed:1869456
instantaneous_ops_per_sec:0
total_net_input_bytes:96816810
total_net_output_bytes:1317602132
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:500000
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:365
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:3ff306564275573723bb08dbcdd2f3c443791118
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:8.453039
used_cpu_user:11.811691
used_cpu_sys_children:0.003920
used_cpu_user_children:0.000916

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=4,expires=0,avg_ttl=0
127.0.0.1:6379>

8,Redis数据库实例

Redis中数据库实例只能由Redis服务来创建和维护,开发人员不能修改和自行创建数据库实例。默认情况下,Redis启动后会自动创建16个数据库,并编号为 0 -15。

//存到0号库里

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"

//切到1号库去找,找不到

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get k1
(nil)
127.0.0.1:6379[1]> select 0  //切回0号库又找到了
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> select 16  //默认到15
(error) ERR DB index is out of range
127.0.0.1:6379>


9,查看当前库数据条数

127.0.0.1:6379> dbsize
(integer) 5
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> dbsize
(integer) 0
127.0.0.1:6379[1]>

0号库默认有四个

10,查看当前库所有key

127.0.0.1:6379> keys *
1) "mylist"
2) "k1"
3) "myset:__rand_int__"
4) "key:__rand_int__"
5) "counter:__rand_int__"
127.0.0.1:6379>

11,清空数据库

127.0.0.1:6379> flushdb  //清空当前库
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> flushall   //清空所有库
25251:M 11 Jun 2022 23:44:45.759 * DB saved on disk
OK
127.0.0.1:6379>

12,查看resis配置信息

127.0.0.1:6379> config get *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""
  7) "cluster-announce-ip"
  8) ""
  9) "unixsocket"
 10) ""
 11) "logfile"
 12) ""
 13) "pidfile"
 14) ""
 15) "slave-announce-ip"
 16) ""
 17) "replica-announce-ip"
 18) ""
 19) "maxmemory"
 20) "0"
 21) "proto-max-bulk-len"
 22) "536870912"
 23) "client-query-buffer-limit"
 24) "1073741824"
 25) "maxmemory-samples"
 26) "5"
 27) "lfu-log-factor"
 28) "10"
 29) "lfu-decay-time"
 30) "1"
 31) "timeout"
 32) "0"
 33) "active-defrag-threshold-lower"
 34) "10"
 35) "active-defrag-threshold-upper"
 36) "100"
 37) "active-defrag-ignore-bytes"
 38) "104857600"
 39) "active-defrag-cycle-min"
 40) "5"
 41) "active-defrag-cycle-max"
 42) "75"
 43) "active-defrag-max-scan-fields"
 44) "1000"
 45) "auto-aof-rewrite-percentage"
 46) "100"
 47) "auto-aof-rewrite-min-size"
 48) "67108864"
 49) "hash-max-ziplist-entries"
 50) "512"
 51) "hash-max-ziplist-value"
 52) "64"
 53) "stream-node-max-bytes"
 54) "4096"
 55) "stream-node-max-entries"
 56) "100"
 57) "list-max-ziplist-size"
 58) "-2"
 59) "list-compress-depth"
 60) "0"
 61) "set-max-intset-entries"
 62) "512"
 63) "zset-max-ziplist-entries"
 64) "128"
 65) "zset-max-ziplist-value"
 66) "64"
 67) "hll-sparse-max-bytes"
 68) "3000"
 69) "lua-time-limit"
 70) "5000"
 71) "slowlog-log-slower-than"
 72) "10000"
 73) "latency-monitor-threshold"
 74) "0"
 75) "slowlog-max-len"
 76) "128"
 77) "port"
 78) "6379"
 79) "cluster-announce-port"
 80) "0"
 81) "cluster-announce-bus-port"
 82) "0"
 83) "tcp-backlog"
 84) "511"
 85) "databases"
 86) "16"
 87) "repl-ping-slave-period"
 88) "10"
 89) "repl-ping-replica-period"
 90) "10"
 91) "repl-timeout"
 92) "60"
 93) "repl-backlog-size"
 94) "1048576"
 95) "repl-backlog-ttl"
 96) "3600"
 97) "maxclients"
 98) "4064"
 99) "watchdog-period"
100) "0"
101) "slave-priority"
102) "100"
103) "replica-priority"
104) "100"
105) "slave-announce-port"
106) "0"
107) "replica-announce-port"
108) "0"
109) "min-slaves-to-write"
110) "0"
111) "min-replicas-to-write"
112) "0"
113) "min-slaves-max-lag"
114) "10"
115) "min-replicas-max-lag"
116) "10"
117) "hz"
118) "10"
119) "cluster-node-timeout"
120) "15000"
121) "cluster-migration-barrier"
122) "1"
123) "cluster-slave-validity-factor"
124) "10"
125) "cluster-replica-validity-factor"
126) "10"
127) "repl-diskless-sync-delay"
128) "5"
129) "tcp-keepalive"
130) "300"
131) "cluster-require-full-coverage"
132) "yes"
133) "cluster-slave-no-failover"
134) "no"
135) "cluster-replica-no-failover"
136) "no"
137) "no-appendfsync-on-rewrite"
138) "no"
139) "slave-serve-stale-data"
140) "yes"
141) "replica-serve-stale-data"
142) "yes"
143) "slave-read-only"
144) "yes"
145) "replica-read-only"
146) "yes"
147) "slave-ignore-maxmemory"
148) "yes"
149) "replica-ignore-maxmemory"
150) "yes"
151) "stop-writes-on-bgsave-error"
152) "yes"
153) "daemonize"
154) "no"
155) "rdbcompression"
156) "yes"
157) "rdbchecksum"
158) "yes"
159) "activerehashing"
160) "yes"
161) "activedefrag"
162) "no"
163) "protected-mode"
164) "yes"
165) "repl-disable-tcp-nodelay"
166) "no"
167) "repl-diskless-sync"
168) "no"
169) "aof-rewrite-incremental-fsync"
170) "yes"
171) "rdb-save-incremental-fsync"
172) "yes"
173) "aof-load-truncated"
174) "yes"
175) "aof-use-rdb-preamble"
176) "yes"
177) "lazyfree-lazy-eviction"
178) "no"
179) "lazyfree-lazy-expire"
180) "no"
181) "lazyfree-lazy-server-del"
182) "no"
183) "slave-lazy-flush"
184) "no"
185) "replica-lazy-flush"
186) "no"
187) "dynamic-hz"
188) "yes"
189) "maxmemory-policy"
190) "noeviction"
191) "loglevel"
192) "notice"
193) "supervised"
194) "no"
195) "appendfsync"
196) "everysec"
197) "syslog-facility"
198) "local0"
199) "appendonly"
200) "no"
201) "dir"
202) "/home/senrsl/redis/redis-5.0.14"
203) "save"
204) "3600 1 300 100 60 10000"
205) "client-output-buffer-limit"
206) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
207) "unixsocketperm"
208) "0"
209) "slaveof"
210) ""
211) "notify-keyspace-events"
212) ""
213) "bind"
214) ""
127.0.0.1:6379> config get port
1) "port"
2) "6379"
127.0.0.1:6379>

13, 五种数据结构

string:单key单value;

list: 单key多有序value,可以重复。

set:单key多无序value;

hash:单key对象(属性:值)

zset: 单key多有序value,根据设置的规则自动排序。

14,操作key命令

127.0.0.1:6379> keys *  //查看所有key
1) "hello"
2) "k2"
3) "k1"
127.0.0.1:6379> keys k*  //查看以k开头的key
1) "k2"
2) "k1"
127.0.0.1:6379> keys h*o  //* 通配符中间内容
1) "hello"
127.0.0.1:6379> keys h?o
(empty list or set)
127.0.0.1:6379> keys h?llo  //?只匹配一个字符
1) "hello"
127.0.0.1:6379> keys h[abc]llo
(empty list or set)
127.0.0.1:6379> keys h[abcde]llo //匹配[]里面的一个字符
1) "hello"
127.0.0.1:6379>

15,判断key是否存在

127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k3
(integer) 0
127.0.0.1:6379> exists k1 k2 k3
(integer) 2
127.0.0.1:6379>

16,移动指定key到指定库

127.0.0.1:6379> move k1 1
(integer) 1
127.0.0.1:6379> keys *
1) "hello"
2) "k2"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "k1"
127.0.0.1:6379[1]>

17,设置key最大生存时间

127.0.0.1:6379> expire k2 20  //设置k2 生存时间20秒
(integer) 1
127.0.0.1:6379> ttl k2
(integer) 15
127.0.0.1:6379> ttl k2
(integer) 12
127.0.0.1:6379> ttl k2
(integer) 6
127.0.0.1:6379> ttl k2
(integer) 1
127.0.0.1:6379> ttl k2
(integer) -2
127.0.0.1:6379> keys *
1) "hello"
127.0.0.1:6379>

18,查看指定key剩余生存时间

ttl time to live

-1是永不超时、-2是没有这个key

127.0.0.1:6379[1]> ttl k1
(integer) -1
127.0.0.1:6379[1]> keys *
1) "k1"
127.0.0.1:6379[1]> ttl k1
(integer) -1
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> ttl k1
(integer) -2
127.0.0.1:6379>

19,查看key数据类型

127.0.0.1:6379> type hello
string
127.0.0.1:6379>

20,重命名key

127.0.0.1:6379> rename hello k2
OK
127.0.0.1:6379> keys *
1) "k2"
127.0.0.1:6379>


21,删除key

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
127.0.0.1:6379> 25251:M 12 Jun 2022 00:44:46.074 * 1 changes in 3600 seconds. Saving...
                                                                                       25251:M 12 Jun 2022 00:44:46.077 * Background saving started by pid 26069
                             26069:C 12 Jun 2022 00:44:46.080 * DB saved on disk
                                                                                26069:C 12 Jun 2022 00:44:46.084 * RDB: 0 MB of memory used by copy-on-write
                         25251:M 12 Jun 2022 00:44:46.177 * Background saving terminated with success
127.0.0.1:6379>
127.0.0.1:6379> del k1 k2 k3 k4 k5
(integer) 2
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>

22,字符串操作

127.0.0.1:6379> set nameA AAAA
OK
127.0.0.1:6379> set ageA 100
OK
127.0.0.1:6379> keys *
1) "nameA"
2) "ageA"
127.0.0.1:6379> get nameA    //获取key value
"AAAA"
127.0.0.1:6379> get ageA
"100"
127.0.0.1:6379> set ageA 80
OK
127.0.0.1:6379> get ageA
"80"
127.0.0.1:6379> set phoneA 132
OK
127.0.0.1:6379> append phone 8888 //append时如果key不存在会创建
(integer) 4
127.0.0.1:6379> get phone
"8888"
127.0.0.1:6379> append phoneA 8888  //追加
(integer) 7
127.0.0.1:6379> get phone
"8888"
127.0.0.1:6379> get phoneA
"1328888"
127.0.0.1:6379> strlen phoneA  //Value长度
(integer) 7
127.0.0.1:6379> incr ageA
(integer) 81
127.0.0.1:6379> incr ageA  //自增加1
(integer) 82
127.0.0.1:6379>

127.0.0.1:6379> incr ageA
(integer) 83
127.0.0.1:6379> decr ageA //自减1
(integer) 82
127.0.0.1:6379>

127.0.0.1:6379> incrby ageA 10 //原值加10
(integer) 92
127.0.0.1:6379> decrby ageA 5 //原值减5
(integer) 87

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> getrange hello 1 3 //字符串截取
"orl"
127.0.0.1:6379> getrange hello 0 -1 //从零到右侧数-1
"world"
127.0.0.1:6379> getrange hello -4 -2 从右侧第四个到右侧第二个
"orl"
127.0.0.1:6379>

127.0.0.1:6379> setrange hello 2 dlr //从index2开始向后覆盖
(integer) 5
127.0.0.1:6379> get hello
"wodlr"
127.0.0.1:6379> setrange hello 2 rld
(integer) 5
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> setrange hello 2 rlds
(integer) 6
127.0.0.1:6379> get hello
"worlds"
127.0.0.1:6379> 

127.0.0.1:6379> setex hello 20 worldworld  //设置内容的时候同时设置失效时间
OK
127.0.0.1:6379> ttl hello
(integer) 16
127.0.0.1:6379> get hello
"worldworld"
127.0.0.1:6379>

127.0.0.1:6379> setnx hello world  //设置当内容不存在时
(integer) 1
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> setnx hello world222
(integer) 0
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379>

27.0.0.1:6379> mset hello world333 nameA nameValue k1 v1  //批量设置
OK
127.0.0.1:6379> keys *
1) "k1"
2) "nameA"
3) "phoneA"
4) "phone"
5) "hello"
6) "ageA"
127.0.0.1:6379> mget hello nameA k1  //批量get
1) "world333"
2) "nameValue"
3) "v1"
127.0.0.1:6379> msetnx hello world4 k2 v2 k3 v3 //当有一个存在时,全部不成功
(integer) 0
127.0.0.1:6379> keys *
1) "k1"
2) "nameA"
3) "phoneA"
4) "phone"
5) "hello"
6) "ageA"
127.0.0.1:6379> msetnx  k2 v2 k3 v3   //全部不存在时,成功
(integer) 1
127.0.0.1:6379> keys *
1) "k1"
2) "nameA"
3) "k3"
4) "k2"
5) "phoneA"
6) "phone"
7) "hello"
8) "ageA"
127.0.0.1:6379>

23,list

单key : 多有序value

127.0.0.1:6379> flushall
1373:M 28 Jun 2022 14:58:35.801 * DB saved on disk
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> lpush list01 1 2 3 //left push 往左侧插入,插到表头
(integer) 3
127.0.0.1:6379> lrange list01 0 2 //范围查看,从index0到2
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> lpush list01 4 5
(integer) 5
127.0.0.1:6379> lrange list01 0 10
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379>

127.0.0.1:6379> lrange list01 0 -1  //全部范围
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379>

127.0.0.1:6379> rpush list02 a b c  //right push 往右侧插入,插到表尾
(integer) 3
127.0.0.1:6379> lrange list02 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> rpush list02 d e f
(integer) 6
127.0.0.1:6379> lrange list02 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
127.0.0.1:6379>

127.0.0.1:6379> lpop list02  //左侧移出一个
"a"
127.0.0.1:6379> rpop list02 //右侧移出一个
"f"
127.0.0.1:6379> lrange list02 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
127.0.0.1:6379> 

127.0.0.1:6379> lindex list02 2  //获取指定索引
"d"
127.0.0.1:6379> rindex list 2
(error) ERR unknown command `rindex`, with args beginning with: `list`, `2`,
127.0.0.1:6379> llen list02  //获取list长度
(integer) 4
127.0.0.1:6379>

127.0.0.1:6379> lpush list04 a b a c a d a e a f a  g
(integer) 12
127.0.0.1:6379> lrem list04 2 a  //count = 2,大于0,从左侧开始移除两个a
(integer) 2
127.0.0.1:6379> lrange list04 0 -1
 1) "g"
 2) "f"
 3) "e"
 4) "a"
 5) "d"
 6) "a"
 7) "c"
 8) "a"
 9) "b"
10) "a"
127.0.0.1:6379> lrem list04 -1 a //count<0,从右侧开始移除count个a
(integer) 1
127.0.0.1:6379> lrange list04 0 -1
1) "g"
2) "f"
3) "e"
4) "a"
5) "d"
6) "a"
7) "c"
8) "a"
9) "b"
127.0.0.1:6379> lrem list04 0 a //count==0,移除全部a
(integer) 3
127.0.0.1:6379> lrange list04 0 -1
1) "g"
2) "f"
3) "e"
4) "d"
5) "c"
6) "b"
127.0.0.1:6379> ltrim list04 1 5  //截取1-5,赋值给list04
OK
127.0.0.1:6379> lrange list04 0 -1
1) "f"
2) "e"
3) "d"
4) "c"
5) "b"
127.0.0.1:6379> lset list04 1 h  //设置索引为1的值为h
OK
127.0.0.1:6379> lrange list04 0 -1
1) "f"
2) "h"
3) "d"
4) "c"
5) "b"
127.0.0.1:6379> linsert list04 before h i  //把i 插入到h之前
(integer) 6
127.0.0.1:6379> linsert list04 after h j  //把j 插入到h之后
(integer) 7
127.0.0.1:6379> lrange list04 0 -1
1) "f"
2) "i"
3) "h"
4) "j"
5) "d"
6) "c"
7) "b"
127.0.0.1:6379>


24,set集合

Redis Set 是String类型无序集合,成员唯一。value 没有顺序,且不能重复

127.0.0.1:6379> sadd set01 v1  //向set01中添加成员v1
(integer) 1
127.0.0.1:6379> sadd set01 v2
(integer) 1
127.0.0.1:6379> sadd set01 v3
(integer) 1
127.0.0.1:6379> sadd set01 v3
(integer) 0
127.0.0.1:6379> smembers set01 //查看set01集合
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379> sadd set01 v4 v5 v6  //添加v4 v5 v6 到set01集合
(integer) 3
127.0.0.1:6379> smembers set01
1) "v4"
2) "v1"
3) "v2"
4) "v3"
5) "v5"
6) "v6"
127.0.0.1:6379> scard set01  //获取size
(integer) 6
127.0.0.1:6379> sadd set02 v1 v2 v3 v5 v6 v7
(integer) 6
127.0.0.1:6379> sdiff set01 set02 //返回第一个集合与其他集合之间差异
1) "v4"
127.0.0.1:6379> sdiffstore set03 set01 set02 //返回第一个集合set01与其他集合set02差异,并存储在set03中
(integer) 1
127.0.0.1:6379> smembers set03
1) "v4"
127.0.0.1:6379> sinter set01 set02 //返回给定所有集合交集
1) "v1"
2) "v2"
3) "v3"
4) "v5"
5) "v6"
127.0.0.1:6379> sinter set01 set02 set03
(empty list or set)
127.0.0.1:6379> sismember set01 v1 //判断v1是否存在于set01
(integer) 1
127.0.0.1:6379> smove set01 set03 v2 //将v2从set01移动到set03
(integer) 1
127.0.0.1:6379> smembers set01 //返回所有成员
1) "v3"
2) "v4"
3) "v1"
4) "v5"
5) "v6"
127.0.0.1:6379> smembers set03
1) "v2"
2) "v4"
127.0.0.1:6379> spop set01   //移除并返回集合中的一个随机元素
"v4"
127.0.0.1:6379> smembers set01
1) "v3"
2) "v1"
3) "v5"
4) "v6"
127.0.0.1:6379> srandmember set01 //返回集合中一个或多个随机数
"v6"
127.0.0.1:6379> srem set01 v5 v6 //移除set01集合中多个成员
(integer) 2
127.0.0.1:6379> sunion set01 set02 //返回所有给定集合中并集
1) "v1"
2) "v3"
3) "v2"
4) "v5"
5) "v6"
6) "v7"
127.0.0.1:6379> sunionstore set04 set01 set02  //返回set01、set02的并集并存储到set04中
(integer) 6
127.0.0.1:6379> smembers set04
1) "v1"
2) "v3"
3) "v2"
4) "v5"
5) "v6"
6) "v7"
127.0.0.1:6379> sscan set01 0  //迭代集合元素
1) "0"
2) 1) "v3"
   2) "v1"
127.0.0.1:6379> smembers set01
1) "v3"
2) "v1"
127.0.0.1:6379>

25,hash

key[ filed:value , filed2:value2 ]

127.0.0.1:6379> hmset key1 name1 value1 name2 value2  //key1增加name1:value1,name2:valuie2
OK
127.0.0.1:6379> hgetall key1 //获取key1所有kv
1) "name1"
2) "value1"
3) "name2"
4) "value2"
127.0.0.1:6379> hdel key1 name2 //删除key1中的name2:value2
(integer) 1
127.0.0.1:6379> hgetall key1
1) "name1"
2) "value1"
127.0.0.1:6379> hexists key1 name1 //查看key1中name1是否存在
(integer) 1

127.0.0.1:6379> hget key1 name1
"value1"
127.0.0.1:6379> hset key1 name3 value3 age 10
(integer) 2
127.0.0.1:6379> hgetall key1
1) "name1"
2) "value1"
3) "name3"
4) "value3"
5) "age"
6) "10"
127.0.0.1:6379> hincrby key1 age 1 //key1中整数字段age加1
(integer) 11
127.0.0.1:6379> hget key1 age
"11"
127.0.0.1:6379> hset key1  score 11.11
(integer) 1
127.0.0.1:6379> hincrbyfloat key1 score 0.1 //key1中float字段score加0.1
"11.21"

127.0.0.1:6379> hkeys key1 //获取key1中所有key列表
1) "name1"
2) "name3"
3) "age"
4) "score"
127.0.0.1:6379> hlen key1  //获取key1中字段数量
(integer) 4
127.0.0.1:6379> hmget key1 name1 age score //批量获取
1) "value1"
2) "11"
3) "11.21"
127.0.0.1:6379> hsetnx key1 name1 value2 //只有字段不存在时,新增字段
(integer) 0
127.0.0.1:6379> hsetnx key1 name4 value4
(integer) 1
127.0.0.1:6379> hvals key1  //获取key1中所有value列表
1) "value1"
2) "value3"
3) "11"
4) "11.21"
5) "value4"
127.0.0.1:6379> hscan key1 0  //迭代
1) "0"
2)  1) "name1"
    2) "value1"
    3) "name3"
    4) "value3"
    5) "age"
    6) "11"
    7) "score"
    8) "11.21"
    9) "name4"
   10) "value4"
127.0.0.1:6379>


26,有序集合zset

通过hash表实现,添加删除查找复杂度都是O(1)

items内容大于64时,同时使用hash和skiplist两种设计,skiplist为 O(log(n))

每个元素会关联一个double类型分数,redis通过分数对成员从小到大排序。

value唯一,分数可以重复。

27.0.0.1:6379> zadd  zset01 10 value1  //添加value1到zset01集合,value1的score是10
(integer) 1
127.0.0.1:6379> zadd  zset01 11 value2
(integer) 1
127.0.0.1:6379> zadd  zset01 12 value3
(integer) 1
127.0.0.1:6379> zadd  zset01 10.01 value4
(integer) 1
127.0.0.1:6379> zadd  zset01 10.01 value4  //value4重复,不添加
(integer) 0
127.0.0.1:6379> zrange zset01 0 10 withscores  //通过索引区间返回有序集合成员
1) "value1"
2) "10"
3) "value4"
4) "10.01"
5) "value2"
6) "11"
7) "value3"
8) "12"
127.0.0.1:6379> zadd zset02 11 value21 13 value22 15 value23 //批量添加 zset02{value21(11),value22(13),value23(15)}
(integer) 3
127.0.0.1:6379> zcard zset01 //获取成员数
(integer) 4

127.0.0.1:6379> zcount zset01 10 15  //计算有几个成员的分数在10-15之间
(integer) 4
127.0.0.1:6379> zrange zset01 0 10 withscores
1) "value1"
2) "10"
3) "value4"
4) "10.01"
5) "value2"
6) "11"
7) "value3"
8) "12"
127.0.0.1:6379> zincrby zset01 2 value1  //给zset01中value1加2即 10+2 =12
"12"
127.0.0.1:6379> zrange zset01 0 10 withscores
1) "value4"
2) "10.01"
3) "value2"
4) "11"
5) "value1"
6) "12"
7) "value3"
8) "12"

127.0.0.1:6379> zrange zset02 0 10
1) "value21"
2) "value22"
3) "value23"
127.0.0.1:6379> zadd zset02 11 value2 12 value3
(integer) 2
127.0.0.1:6379> zinterstore zset03 2  zset01 zset02 //计算zset01、zset02交集,并将交集score相加存储到zset03
(integer) 2
127.0.0.1:6379> zrange zset03 0 10 withscores
1) "value2"
2) "22"
3) "value3"
4) "24"
127.0.0.1:6379>

127.0.0.1:6379> zrangebyscore zset01 11 13 withscores //获取分数在11-13之间的数据
1) "value2"
2) "11"
3) "value1"
4) "12"
5) "value3"
6) "12"
127.0.0.1:6379>

127.0.0.1:6379> zrem zset01 value2  //从zset01中删除value2
(integer) 1
127.0.0.1:6379> zrange zset01 0 -1 withscores
1) "value4"
2) "10.01"
3) "value1"
4) "12"
5) "value3"
6) "12"

127.0.0.1:6379> zrank zset01 value1  //返回value1的索引
(integer) 1
127.0.0.1:6379> zrank zset01 value4
(integer) 0
127.0.0.1:6379> zscore zset01 value1  //获取value1的score
"12"
127.0.0.1:6379> zrevrank zset01 value1  //获取value1的反向索引
(integer) 1
127.0.0.1:6379> zrevrank zset01 value4
(integer) 2
127.0.0.1:6379>

27,redis配置文件

redis.conf

port 运行端口,默认6379

bind 默认是127.0.0.1 一般配置为真实ip

使用修改后的配置文件启动

[senrsl@localhost redis-5.0.14]$ redis-server shutdown
3240:C 28 Jun 2022 20:52:49.817 # Fatal error, can't open config file 'shutdown'
[senrsl@localhost redis-5.0.14]$ redis-cli shutdown
1373:M 28 Jun 2022 20:53:14.168 # User requested shutdown...
1373:M 28 Jun 2022 20:53:14.168 * Saving the final RDB snapshot before exiting.
1373:M 28 Jun 2022 20:53:14.169 * DB saved on disk
1373:M 28 Jun 2022 20:53:14.169 # Redis is now ready to exit, bye bye...
[1]+  完成                  redis-server
[senrsl@localhost redis-5.0.14]$ redis-server redis.conf
3244:C 28 Jun 2022 20:53:24.083 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
3244:C 28 Jun 2022 20:53:24.083 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=3244, just started
3244:C 28 Jun 2022 20:53:24.083 # Configuration loaded
3244:M 28 Jun 2022 20:53:24.084 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
3244:M 28 Jun 2022 20:53:24.084 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
3244:M 28 Jun 2022 20:53:24.084 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._                                                 
           _.-``__ ''-._                                            
      _.-``    `.  `_.  ''-._           Redis 5.0.14 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6380
 |    `-._   `._    /     _.-'    |     PID: 3244
  `-._    `-._  `-./  _.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |           http://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |                                 
  `-._    `-._`-.__.-'_.-'    _.-'                                  
      `-._    `-.__.-'    _.-'                                      
          `-._        _.-'                                          
              `-.__.-'                                              

3244:M 28 Jun 2022 20:53:24.085 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
3244:M 28 Jun 2022 20:53:24.085 # Server initialized
3244:M 28 Jun 2022 20:53:24.085 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
3244:M 28 Jun 2022 20:53:24.085 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
3244:M 28 Jun 2022 20:53:24.085 * DB loaded from disk: 0.000 seconds
3244:M 28 Jun 2022 20:53:24.085 * Ready to accept connections

端口修改成了6380,bind改成了192.168.0.121

1)连接与关闭

[senrsl@localhost redis-5.0.14]$ redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
not connected> quit
[senrsl@localhost redis-5.0.14]$ redis-cli -h 192.168.0.121 -p 6380
192.168.0.121:6380> keys *
 1) "list04"
 2) "s1"
 3) "set03"
 4) "set04"
 5) "s3"
 6) "set01"
 7) "zset02"
 8) "zset01"
 9) "key1"
10) "list03"
11) "4"
12) "s2"
13) "list02"
14) "set02"
15) "list01"
16) "zset03"
192.168.0.121:6380> quit
[senrsl@localhost redis-5.0.14]$ redis-cli shutdown
Could not connect to Redis at 127.0.0.1:6379: Connection refused
[senrsl@localhost redis-5.0.14]$ redis-cli -h 192.168.0.121 -p 6380 shutdown
3252:M 28 Jun 2022 20:55:41.484 # User requested shutdown...
3252:M 28 Jun 2022 20:55:41.484 * Saving the final RDB snapshot before exiting.
3252:M 28 Jun 2022 20:55:41.485 * DB saved on disk
3252:M 28 Jun 2022 20:55:41.485 * Removing the pid file.
3252:M 28 Jun 2022 20:55:41.485 # Redis is now ready to exit, bye bye...
[1]+  完成                  redis-server redis.conf
[senrsl@localhost redis-5.0.14]$

2)tcp-keepalive TCP连接保活策略

单位为秒,默认300

3)日志

# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice

# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile ""  //默认空输出到控制台

4)默认数据库数

# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16  //默认16个

5)测试

[senrsl@localhost redis-5.0.14]$ redis-server redis.conf &
[1] 3346
[senrsl@localhost redis-5.0.14]$ ll ../
总用量 1964
drwxrwxr-x. 6 senrsl senrsl    4096 6月  28 21:08 redis-5.0.14
-rw-r--r--. 1 senrsl senrsl 2000179 6月  11 22:48 redis-5.0.14.tar.gz
-rw-rw-r--. 1 senrsl senrsl    2869 6月  28 21:08 redis5016.log
[senrsl@localhost redis-5.0.14]$

6)安全配置

################################## SECURITY ###################################

# Require clients to issue AUTH <PASSWORD> before processing any other
# commands.  This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
# requirepass foobared

需要配置protected-mode为yes才可以生效

# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
#    "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes  //一般为no


28,持久化

1) RDB策略 RedisDataBase。

    多长时间内写了多少次,自动触发一次持久化操作。

    默认策略 1分钟改1万次,5分钟改10次,15分钟改1次。

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

存储位置为

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./

dir目录的dump.rdb文件。


2) AOF策略

appendonly,采用操作日志来记录每一次写操作,每次Redis启动时都会执行一遍日志中命令。用来弥补RDB策略。

############################## APPEND ONLY MODE ###############################

# By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).
#
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of writes in a
# dramatic event like a server power outage, or a single write if something
# wrong with the Redis process itself happens, but the operating system is
# still running correctly.
#
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.

appendonly no

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

根据数据特点决定是否开启。效率低。

29,事务

保证操作原子性。

redis把一组命令放在一起进行序列化,然后一起执行,保证部分原子性。

127.0.0.1:6379> flushall
3504:M 28 Jun 2022 21:40:53.072 * DB saved on disk
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> multi    //开启事务
OK
127.0.0.1:6379> set k1 v1  //命令1
QUEUED
127.0.0.1:6379> set k1 v2 //命令2
QUEUED
127.0.0.1:6379> set k2 v2  //命令3
QUEUED
127.0.0.1:6379> exec  //执行事务
1) OK
2) OK
3) OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
127.0.0.1:6379>

部分原子性解释:

    压入队列时如果出现错误,其他所有命令都不会执行。

    压入队列成功时,但执行时出错,之前执行的不会回退。

discard:放弃事务。

watch 监控一个或多个键

127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> set balance2 1000
OK
127.0.0.1:6379> set version 1
OK
127.0.0.1:6379> watch version
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby balance 50
QUEUED
127.0.0.1:6379> incrby balance2 50
QUEUED
127.0.0.1:6379> incr version
QUEUED

//执行前在新窗口修改了version

//导致事务失败

127.0.0.1:6379> exec
(nil) 
127.0.0.1:6379> get balance
"100"
127.0.0.1:6379>

unwatch 放弃监控所有键

30,发布与订阅

客户端订阅频道,发布者往频道发消息,所有订阅此频道的客户端都能接收消息。

1)subscribe:订阅一个或多个频道消息;

2)publish:发布消息到指定频道

127.0.0.1:6379> subscribe ch1 ch2 ch3  //订阅
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "ch1"
3) (integer) 1
1) "subscribe"
2) "ch2"
3) (integer) 2
1) "subscribe"
2) "ch3"
3) (integer) 3

1) "message"
2) "ch1"
3) "hello"

127.0.0.1:6379> publish ch1 hello //发布
(integer) 1
127.0.0.1:6379>

31,主从复制

主机数据更新后根据配置和策略,自动同步到从机的master/slave机制,master以写为主,slave以读为主。

主少从多,主写从读,读写分离,主写同步复制到从。

1)启动三个Redis。

[senrsl@localhost redis-5.0.14]$ cp redis.conf redis6379.conf
[senrsl@localhost redis-5.0.14]$ cp redis.conf redis6380.conf
[senrsl@localhost redis-5.0.14]$ cp redis.conf redis6381.conf
[senrsl@localhost redis-5.0.14]$ vi redis6379.conf
[senrsl@localhost redis-5.0.14]$

修改6379服务

port 6379 //对应端口

bind 127.0.0.1 //实际用实际IP

pidfile /var/run/redis_6379.pid

logfile "/home/senrsl/redis/redis5016_6379.log"

dbfilename dump_6379.rdb

其他对应

启动

[senrsl@localhost redis-5.0.14]$ redis-server redis6379.conf &
[1] 4241
[senrsl@localhost redis-5.0.14]$ ps -ef | grep redis
senrsl     4241   3811  0 23:57 pts/1    00:00:00 redis-server 127.0.0.1:6379
senrsl     4246   3811  0 23:58 pts/1    00:00:00 grep --color=auto redis
[senrsl@localhost redis-5.0.14]$ redis-server redis6380.conf &
[2] 4247
[senrsl@localhost redis-5.0.14]$ redis-server redis6381.conf &
[3] 4253
[senrsl@localhost redis-5.0.14]$ ps -ef | grep redis
senrsl     4241   3811  0 23:57 pts/1    00:00:00 redis-server 127.0.0.1:6379
senrsl     4247   3811  0 23:58 pts/1    00:00:00 redis-server 192.168.0.121:6380
senrsl     4253   3811  0 23:58 pts/1    00:00:00 redis-server 127.0.0.1:6381
senrsl     4258   3811  0 23:58 pts/1    00:00:00 grep --color=auto redis
[senrsl@localhost redis-5.0.14]$

2)进入

[senrsl@localhost redis-5.0.14]$ redis-cli -p 6379
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>

[senrsl@localhost ~]$ redis-cli -h 192.168.0.121 -p 6380
192.168.0.121:6380>

[senrsl@localhost ~]$ redis-cli -p 6381
127.0.0.1:6381>

3)角色

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:bc4225a3c105c447fa51e04e81e4f6a8d8d353e7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>

默认都是主机master

三台独立

4)设置主从关系 - 设从不设主

6380、6381 设置主机为6379

192.168.0.121:6380> slaveof 127.0.0.1 6379
OK
192.168.0.121:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:9052b98e806959d5e73bc7c49bc69dd2ba07d2dd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
192.168.0.121:6380>

6379查看

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.0.121,port=6380,state=online,offset=42,lag=1
master_replid:9052b98e806959d5e73bc7c49bc69dd2ba07d2dd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.0.121,port=6380,state=online,offset=70,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=70,lag=0
master_replid:9052b98e806959d5e73bc7c49bc69dd2ba07d2dd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
127.0.0.1:6379>

默认全量复制。主动关系连接后自动从主机复制库。

增量复制,主库写数据自动同步到从库。

5)主写从读,读写分离

master可以读也能读

slave不能写只能读

192.168.0.121:6380> set k3 v3
(error) READONLY You can't write against a read only replica.
192.168.0.121:6380>

6)主机宕机,从机原地待命

[senrsl@localhost redis-5.0.14]$ redis-cli -p 6379 shutdown
[1]   完成                  redis-server redis6379.conf
[senrsl@localhost redis-5.0.14]$ ps -ef | grep redis
senrsl     4247   3811  0 6月28 pts/1   00:00:00 redis-server 192.168.0.121:6380
senrsl     4253   3811  0 6月28 pts/1   00:00:00 redis-server 127.0.0.1:6381
senrsl     4314   4266  0 00:01 pts/0    00:00:00 redis-cli -h 192.168.0.121 -p 6380
senrsl     4339   4320  0 00:01 pts/2    00:00:00 redis-cli -p 6381
senrsl     4387   3811  0 00:11 pts/1    00:00:00 grep --color=auto redis
[senrsl@localhost redis-5.0.14]$

192.168.0.121:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:542
master_link_down_since_seconds:30
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:9052b98e806959d5e73bc7c49bc69dd2ba07d2dd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:542
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:542
192.168.0.121:6380>


7),主机恢复,从机自动恢复正常

[senrsl@localhost redis-5.0.14]$ redis-server redis6379.conf &
[4] 4397
[senrsl@localhost redis-5.0.14]$ ps -ef | grep redis
senrsl     4247   3811  0 6月28 pts/1   00:00:01 redis-server 192.168.0.121:6380
senrsl     4253   3811  0 6月28 pts/1   00:00:01 redis-server 127.0.0.1:6381
senrsl     4314   4266  0 00:01 pts/0    00:00:00 redis-cli -h 192.168.0.121 -p 6380
senrsl     4339   4320  0 00:01 pts/2    00:00:00 redis-cli -p 6381
senrsl     4397   3811  0 00:13 pts/1    00:00:00 redis-server 127.0.0.1:6379
senrsl     4404   3811  0 00:13 pts/1    00:00:00 grep --color=auto redis
[senrsl@localhost redis-5.0.14]$

192.168.0.121:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3ccc1cd26da8f4662a5fb2405d83fa3197d2473c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
192.168.0.121:6380>


8)从机宕机

主机自动减少,其他从机不变

[senrsl@localhost ~]$ redis-cli -h 192.168.0.121 -p 6380 shutdown
[senrsl@localhost ~]$

[senrsl@localhost redis-5.0.14]$ redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=196,lag=0
master_replid:3ccc1cd26da8f4662a5fb2405d83fa3197d2473c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:210
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:210
127.0.0.1:6379>

9)从机恢复

从机恢复后,变成主机,需要再次设置为从机。

[senrsl@localhost redis-5.0.14]$ redis-cli -h 192.168.0.121 -p 6380
192.168.0.121:6380> info replication
# Replication
role:master
connected_slaves:0
master_replid:b5dcc87505cd45758f9f4a3e5c874ec94eb7de51
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.0.121:6380> slaveof 127.0.0.1 6379
OK
192.168.0.121:6380>

10)主机宕机,从机上位

6379宕机

[senrsl@localhost redis-5.0.14]$ redis-cli -p 6379 shutdown
[4]+  完成                  redis-server redis6379.conf
[senrsl@localhost redis-5.0.14]$

6380取消slave

192.168.0.121:6380> salveof no one
(error) ERR unknown command `salveof`, with args beginning with: `no`, `one`,
192.168.0.121:6380> slaveof no one
OK
192.168.0.121:6380> info replication
# Replication
role:master
connected_slaves:0
master_replid:edef80a15b43e222184f0c48007806a9ca47c854
master_replid2:3ccc1cd26da8f4662a5fb2405d83fa3197d2473c
master_repl_offset:672
second_repl_offset:673
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:561
repl_backlog_histlen:112
192.168.0.121:6380>

6381设置丛属6380

127.0.0.1:6381> slaveof 192.168.0.121 6380
OK
127.0.0.1:6381>

6380查看丛属

192.168.0.121:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=686,lag=1
master_replid:edef80a15b43e222184f0c48007806a9ca47c854
master_replid2:3ccc1cd26da8f4662a5fb2405d83fa3197d2473c
master_repl_offset:686
second_repl_offset:673
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:561
repl_backlog_histlen:126
192.168.0.121:6380>

11)之前主机6379恢复

依然要重新设置,设置为主机或从机。

12)既是主机,又是从机

如果6379 slaveof 6381,那6381既是主又是从,只要是从就不能写。


庞大的集群结构,减轻一台主机压力,增加延迟时间。


32,哨兵模式

主机宕机、从机上位自动版。

1)主机6379,从机6380、6381

2)配置文件

默认有提供sentinel.conf

自己建简单的

[senrsl@localhost redis-5.0.14]$ touch redis_sentinel.conf
[senrsl@localhost redis-5.0.14]$ vi redis_sentinel.conf
[senrsl@localhost redis-5.0.14]$ cat redis_sentinel.conf
sentinel monitor dc-redis 127.0.0.1 6379 1
[senrsl@localhost redis-5.0.14]$

3) 启动哨兵

[senrsl@localhost redis-5.0.14]$ redis-sentinel redis_sentinel.conf
4590:X 29 Jun 2022 00:45:28.828 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4590:X 29 Jun 2022 00:45:28.828 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=4590, just started
4590:X 29 Jun 2022 00:45:28.828 # Configuration loaded
4590:X 29 Jun 2022 00:45:28.829 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
4590:X 29 Jun 2022 00:45:28.829 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
4590:X 29 Jun 2022 00:45:28.829 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._                                                 
           _.-``__ ''-._                                            
      _.-``    `.  `_.  ''-._           Redis 5.0.14 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 4590
  `-._    `-._  `-./  _.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |           http://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                 
 |    `-._`-._        _.-'_.-'    |                                 
  `-._    `-._`-.__.-'_.-'    _.-'                                  
      `-._    `-.__.-'    _.-'                                      
          `-._        _.-'                                          
              `-.__.-'                                              

4590:X 29 Jun 2022 00:45:28.830 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4590:X 29 Jun 2022 00:45:28.831 # Sentinel ID is dae46325512d7115d01f5532983528d0013c4d5d
4590:X 29 Jun 2022 00:45:28.831 # +monitor master dc-redis 127.0.0.1 6379 quorum 1
4590:X 29 Jun 2022 00:45:28.831 * +slave slave 192.168.0.121:6380 192.168.0.121 6380 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:45:28.832 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ dc-redis 127.0.0.1 6379

4)主机宕机

主机自动变成了6380

4590:X 29 Jun 2022 00:46:15.693 # +sdown master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.693 # +odown master dc-redis 127.0.0.1 6379 #quorum 1/1
4590:X 29 Jun 2022 00:46:15.693 # +new-epoch 1
4590:X 29 Jun 2022 00:46:15.693 # +try-failover master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.694 # +vote-for-leader dae46325512d7115d01f5532983528d0013c4d5d 1
4590:X 29 Jun 2022 00:46:15.694 # +elected-leader master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.694 # +failover-state-select-slave master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.770 # +selected-slave slave 192.168.0.121:6380 192.168.0.121 6380 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.770 * +failover-state-send-slaveof-noone slave 192.168.0.121:6380 192.168.0.121 6380 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.858 * +failover-state-wait-promotion slave 192.168.0.121:6380 192.168.0.121 6380 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.982 # +promoted-slave slave 192.168.0.121:6380 192.168.0.121 6380 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:15.982 # +failover-state-reconf-slaves master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:16.062 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:16.995 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:16.995 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:17.071 # +failover-end master dc-redis 127.0.0.1 6379
4590:X 29 Jun 2022 00:46:17.071 # +switch-master dc-redis 127.0.0.1 6379 192.168.0.121 6380
4590:X 29 Jun 2022 00:46:17.071 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ dc-redis 192.168.0.121 6380
4590:X 29 Jun 2022 00:46:17.071 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ dc-redis 192.168.0.121 6380
4590:X 29 Jun 2022 00:46:47.119 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ dc-redis 192.168.0.121 6380


5)主机恢复

恢复后 6379变成了6380的从机

4590:X 29 Jun 2022 00:48:58.220 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ dc-redis 192.168.0.121 6380
4590:X 29 Jun 2022 00:49:08.218 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ dc-redis 192.168.0.121 6380

33,Jedis操作Redis

Java操作。。。。

新建idea test-redis项目

依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>3.3.0</version>
</dependency>

操作

package dc.test.redis;

import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

/**
 * @author senrsl
 * @ClassName: TestJedis
 * @Package: dc.test.redis
 * @CreateTime: 2022/6/29 12:38
 */
public class TestJedis {

    public static void main(String[] args) {

        //连接
        Jedis jedis = new Jedis("192.168.0.121", 6380);

        //ping pong
        System.out.println("ping pong is " + jedis.ping());

        System.out.println("新增 " + jedis.set("k2", "v2"));

        //get key
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);
        for (String key : keys) {
            System.out.println(key);
        }

        //exits
        System.out.println(jedis.exists("k2"));


        //move
        System.out.println(jedis.move("k2", 1));


        //切换到1号库
        System.out.println(jedis.select(1));

        //获取k2 value
        System.out.println(jedis.get("k2"));


        //事务
        Transaction transaction = jedis.multi();
        transaction.set("k5", "v5");
        transaction.set("k6", "6");
        transaction.incr("k6");
        transaction.exec();

        System.out.println("k5 is "+ jedis.get("k5") + "  k6 is "+jedis.get("k6"));

    }

}


34,可视化界面

redis-desktop-manager


--
senRsl
2022年06月24日14:35:02

没有评论 :

发表评论