Redis
NoSQL 是什么?
- 泛指:非關系型數據庫,隨著Web 2.0 互聯網時代的到來(
高并發)傳統關系型數據庫也難以應付! - 特點:
- 易擴展、大數據量——數據之間沒有關系,容易擴展!
- 大數據量高性能——Redis 每秒寫8萬次,讀11萬次!
- 高可用(支持主備、集群)。
- 四大分類
- 鍵值存儲:Redis
- 列存儲 : HBase
- 文檔存儲:MongoDB
- 圖形存儲: Neo4J
為什么要用Nosql ?
-
為了解決傳統數據庫不能解決高并發讀寫、海量數據的高效率存儲和訪問、高可擴展性和高可用等問題。
-
網站的對數據庫的操作,基本是讀的操作。
-
發展過程:
- 單機年代
- 優化數據結構和索引 + 文件緩存
- Memcached(緩存)+ Mysql + 垂直拆分(讀寫分離)
- 分庫分表 + 水平拆分(Mysql集群)
Redis是什么 ?
- 開源免費以
C語言編寫,遵守BSD協議,支持多種數據結構、網絡、數據持久化、Key-Value的高性能數據庫,以RESP作為Redis客戶端和服務端之前使用的一種通訊協議; - 執行命令是單線程,默認使用 0 號數據庫,默認 16 個數據庫。
- 特點:高性能,多種數據結構、原子操作、事務
應用
- 高速緩存
- 任務隊列
- 發布訂閱系統
- 地圖信息分析
- 分布式集群架構中的session分離
- 計數器、定時器、訪問統計、排行榜。
Redis 安裝
#安裝需要的環境
yum install gcc-c++ -y
# 檢查版本
gcc -v
#上傳redis
tar -zxvf redis-5.0.4.tar.gz -C /usr/local/
#去到路徑下
cd /usr/local/
#重命名
mv redis-5.0.4 redis
#進入
cd redis
#編譯安裝
make && make install
#默認安裝路徑
/usr/local/bin
#執行配置
/usr/local/redis/utils/install_server.sh
修改配置、關閉保護模式、設置后臺進程運行
vim /etc/redis/6379.conf
-----配置 start-----
#bind 127.0.0.1
protected-mode no
daemonize yes
-----配置 end-------
Redis Config
# 網絡
bind 127.0.0.1 # 綁定的ip
protected-mode yes # 保護模式 開關
prot 6379 # 端口
# 通用
daemonize yes # 守護進程模式 開關 默認 為 no
pidfile /var/run/redis_6379.pid # 指定后臺運行配置文件
loglevel notice # 日志4種級別:
# bebug -- 測試/開發階段使用)
# verbose -- 預生產
# notice -- 生產
# warning -- 警告
logfile "" # 日志文件路徑
databases 16 # 數據庫數量,默認 16 個
always-show-logo yes # 啟動顯示Logo 開關
# 持久化
save 900 1 # 900秒內 有1個key進行修改內,進行持久化
save 300 10 # 300秒內 有10個key進行修改內,進行持久化
save 60 10000 # 60秒內 有10000個key進行修改內,進行持久化
stop-writes-on-bgsave-error yes # 持久化時出錯是否繼續工作 開關
rdbcompression yes # 是否對rdb文件進行壓縮、需要耗費CPU資源 開關
rdbchecksum yes # 保存時校驗 開關
dir ./ # 持久化文件目錄
dbfilename dump.rdb # RDB 持久化文件名
# 限制
maxclients 1000 # 連接客戶端的數量
maxmemory <bytes> # 最大內存容量
maxmemory-policy noeviction # 內存負荷時:6種 策略
# noeviction -- 永不過期,返回錯誤
# volatile-lru -- 對過期 key 進行 LRU (默認)
# allkeys-lru -- 刪除 LRU 算法的 key
# volatile-random -- 隨機刪除過期的 key
# allkeys-random -- 隨機刪除
# volatile-ttl -- 刪除即將過期的 key
# AOF
appendonly no # AOF 模式開關,默認開啟 RDB 模式
appendfilename "appendonly.aof" # AOF 持久化的文件名
appendfsync everysec # AOF 持久化策略
# always -- 每次
# everysec -- 每秒
# no -- 不自動執行,可應用系統手動執行
no-appendfsync-on-rewrite no #
auto-aof-rewrite-percentage 100 #
auto-aof-rewrite-min-size 64mb # 設置AOF持久化文件大小,超出超出后定義新文件
Redis 數據類型
5 種 基本類型
Strings(字符串)
- 一個鍵最大能存儲512MB。
- 應用
- 計數器
- 統計
- 對象存儲
# 存
set my_soul "hello Word"
# 取
get my_soul
# 追加內容——如果不存在則Set
append my_soul "Redis"
# 獲取長度
strlen my_soul
# 自增 步長為1 默認是 0
incr my_count
# 自減
decr my_count
# 設置 自增的步長
incrby my_count 10
# 設置 自減的步長
decrby my_count 5
# 截取,0 到 3
getrange my_soul 0 3
getrange my_soul 0 -1 # 返回所有
# 替換,從 1 替換
setrange my_soul 1 love
# 設置過期時間
setex my_soul 30 "Hello World!"
# 不存在則Set,常用于分布式鎖
setnx my_key "MongDB"
msetnx my_key "My" my_key2 "Love" # 原子操作,要么一起成功、要么一起失敗!
# 設置多個值
mset my_key1 my_value1 my_key2 my_value2 # 單機模式語法
mset {my_key}1 my_value {my_key}2 my_value21 # 集群模式語法
# 讀取多個
mget my_key1 my_key2 # 單機模式語法
mget {my_key}1 {my_key}2 # 集群模式寫法
# 讀取修改,如果不存在則返回 nil ,如果存在,返回舊值,設置新值
getset my_db "redis"
List(列表)
- 實際是
鏈表結構。 - 應用
- 消息隊列
# 添加
lpush my_list one # 從左邊添加
rpush my_list_r two # 從右邊添加
linsert my_list before "one" "zero" # 指定某個元素前插入
linsert my_list after "two" "three" # 指定某個元素后插入
# 移除
Lpop mylist # 從左邊移除
Rpop my_list_r # 從右邊移除
lrem my_list 1 one # value = one 移除第一個,可以移除多個
# 讀取
lrange my_list 0 -1 # 讀取全部
lrange my_list 0 1 # 讀取 倒數 1 和 2
lindex my_list 1 # 按下標讀取
Llen my_list # 讀取長度
# 截取
ltrim my_list 1 2 # 截取下標為,1 和 2 的數據
# 移動
rpoplpush my_list my_new_list # 移除最后一個元素、到一個新的列表中
# 更新
lset my_list 0 "my_redis"
Set(集合)
- 無序不重復集合!
- 應用
- 共同關注。
# 添加
sadd my_set "hello"
# 移除
srem my_set "hello" # 移除指定元素
spop my_set # 隨機移除
# 查看
smembers my_set # 查看所有
sismember my_set "hello" # 判斷是否存在
scard my_set # 查看集合總數
# 隨機抽取
srandmember my_set 2 # 隨機抽取2個
# 移動
smove my_set my_new_set "hello" # 指定元素,移到新的集合
# 交集
sinter my_set my_new_set # 兩個集合的交集 應用:微博、B站:共同關注
# 并集
sunion my_set my_new_set # 兩個集合的并集
# 差集,注意位置
sdiff my_set my_new_set # my_set 對于 my_new_set 的差集
sdiff my_new_set my_set # my_new_set 對于 my_set 的差集
Hash(哈希)
- Map 集合
- 應用
- 對象存儲
# 添加
hset my_hash v1 "hello world"
hmset my_hash v1 "v2" v2 "v2" # 添加多個值
# 讀取
hget my_hash v1
hmget my_hash v1 v2 # 讀取多個值
hgetall my_hash # 讀取全部
hlen my_hash # 讀取長度
hexists my_hash v1 # 判斷是否存在
hkeys my_hash # 獲取所有的key
hvals my_hash # 獲取所有的value
# 移除
hdel my_hash v1 # 刪除指定key
# 增量
hset my_hash v3 5 # 設置增量步長
hincrbyf my_hash v3 1 # 加1
hsetnx my_hash v4 "Hello world" # 不存在則添加
Zset(有序集合)
- 應用
- 排行榜
# 添加
zadd my_set 1 one
# 讀取
zrange my_set 0 -1
zcard my_set # 獲取集合數量
zcount my_set 2 5 # 獲取指定區間的數量
# 移除
zrem my_set v1
# 排序
zrangebyscore my_set -inf +inf # 正序:從負無窮到正無窮
zrangebyscore my_set -inf +inf withscores # 正序:并返回values
zrevrange my_set 0 -1 # 倒序
3 種 特殊類型
geospatial 地理位置
- 需要導入地理信息數據
geoadd china:city 121.47 31.23 shanghai
# 獲取指定城市的經緯度
geopos china:city beijing
# 距離
geodist china:city beijing chongqing km
# 附近5千米
georadius china:city 110 30 500 km
hyperloglog
- 基數統計算法
- 應用
- 統計(有誤差、允許有誤差即可使用該算法)
# 添加
pfadd mydata a b c d e f g h
# 查看總數
pfcount mydata
#合并
pfmegre mydataResult mydata1 mydata2
bitmap
- 位存儲
setbit sign 0 0
# 總數
bitcount sign
Redis 事務
- Redis 每條命令都保持原子性,但是事務不保證原子性,不存在關系型數據的隔離級別概念!
# 開啟事物
multi
# 事務隊列,即一組需要執行的命令
set mydata "Hello world!"
lpush myList "Your apples"
# 取消事物
discard
# 執行事務
exec
Redis 發布訂閱
- Redis 發布訂閱(pub/sub)是一種消息通訊模式:發送者(pub)發送消息,訂閱者(sub)接收消息。
# 訂閱頻道
subscribe soul_blog
# 訂閱多個頻道
pssubscribe soul_blog
# 發布
publish soul_blog "Hello,This is Soul blog!!!!"
- 應用
- 實時消息系統
Redis 持久化
- 持久化就是把內存的數據寫到磁盤中去,防止服務宕機了內存數據丟失,重啟服務器之后從磁盤中恢復數據,Redis提供2種持久化機制(
RDB、AOF)。
RDB(Redis DataBase)
- 以時間周期進行快照保存,比
AOF高效,適合大規模的數據且對數據完整沒有要求的場景,缺點是可能會丟失最后一次持久化的數據! - 實現:創建子進程將主進程的數據復制到子進程的內存,由子進程寫入臨時文件中,持久化過程結束后替換上一次的快照文件,子進程退出,釋放內存。
- 觸發保存:
- 符合時間周期
- 執行
flushall命令 - 停止
redis
- 恢復數據:
rdb文件放在Redis啟動目錄即可,啟動時會自檢!
AOF(Append Only File)
- 以 日志 方式對
寫操作進行記錄,恢復數據時進行有序的加載,恢復較慢,每秒同步一次,保存的數據完整性較高。
Redis 主從復制
- 主從復制 是指在Redis 集群時,
一臺主機的數據復制到多臺從機中,數據單向,由主節點到從節點。 - 主要作用:
- 數據冗余:實現數據熱備份。
- 故障恢復:主節點故障時,由子節點提供服務。
- 負載均衡:實現讀寫分離、分擔主節點的壓力,提高并發能力。
- 高可用(集群):主從復制作為集群和哨兵模式的基石。
- 復制的方式
- 全量復制
- 增量復制
Redis 哨兵模式
- **哨兵 **獨立的進程,可以對 Redis 主機 故障后重新投票選舉新的主機。
- 實現原理是 哨兵發起命令,等待Redis響應,從而監控Redis的所有實例。——大多數
哨兵檢測到 Redis 主機故障時,由任意其一哨兵發起投票,對 從機進行新的主機選舉,選舉成功后,切換主機,通過發布訂閱模式通知其他哨兵。
# 集群命令
redis-cli --cluster help
# 創建集群主節點(至少3個主節點,且奇數)
redis-cli --cluster create 172.18.0.21:6379 172.18.0.23:6379 172.18.0.25:6379
# 創建集群主從節點
redis-cli --cluster
create 172.18.0.21:6379
172.18.0.22:6379
172.18.0.23:6379
172.18.0.24:6379
172.18.0.25:6379
172.18.0.26:6379
--cluster-replicas 1 # 配置一臺從機
# 添加主節點
redis-cli --cluster add-node 172.18.0.27:6379
# 添加從節點
redis-cli --cluster add-node 172.18.0.22:6379 172.18.0.21:6379
--cluster-slave --cluster-master-id 117457eab5071954faab5e81c3170600d5192270
# 刪除節點
redis-cli --cluster del-node 172.18.0.28:6379 f6a6957421b80409106cb36be3c7ba41f3b603ff
# 查看集群信息
redis-cli --cluster info 172.18.0.22:6379
# 編寫哨兵配置文件
vim sentinel.conf
#文件內容
# -----------------------配置 strar --------------------------------
# 端口
port 26379
# 后臺進程運行
daemonize yes
# 哨兵的工作目錄
dir /tmp
# 哨兵監控的Redis機器
sentinel monitor soulSentinel 172.18.0.21 6379 1
# Redis 服務的密碼
sentinel auth-pass soulSentinel MYSUPER-secret-123456
# 哨兵 主觀認為 主節點失效 默認 30 秒
sentinel down-after-milliseconds soulSentinel 300
# 故障轉移的超時時間
sentinel failover-timeout soulSentinel 180000
# 通知腳本
sentinel notification-script soulSentinel /var/redis/notify.sh
# 客戶端重新配置主節點參數腳本
sentinel client-reconfig-script soulSentinel /var/redis/reconfig.sh
# -----------------------配置 end --------------------------------
#啟動哨兵
./redis-sentinel sentinel.conf
# 進入哨兵
redis-cli -p 26379
# 查看哨兵狀態
info sentinel
Redis 應用問題
緩存穿透
- 用戶的查詢沒有在Redis中找到,需要向數據庫頻繁操作造成壓力。
- 解決方案:
- 布隆過濾器:一種數據結構,對所有的查詢參數以Hash形式存儲,過濾不非法查詢,避免造成
緩存穿透! - 緩存空對象:設置為空對象,預先緩存!
- 布隆過濾器:一種數據結構,對所有的查詢參數以Hash形式存儲,過濾不非法查詢,避免造成
緩存擊穿
- 高并發對一個key進行訪問,當key失效瞬間,請求直接訪問數據庫,導致數據庫壓力過大。
- 解決方案
- 高頻的Key永不過期。
- 互斥鎖:只允許一個線程訪問,其他需要等待。
緩存雪崩
- Redis 服務器宕機、緩存集體失效!
- 解決方案:
- Redis 高可用。
- 限流降級:緩存失效后,控制讀寫的線程的操作數量。
- 數據預熱:正式部署前,先緩存起來。
Redis 常用指令
# 啟動Redis 服務
./redis-server /etc/redis/6379.conf
# 進入Redis
./redis-cli -p 6379
auth 01Wyl62 # 01Wyl62 為密碼
# Redis 狀態
service redis_6379 status
# 停止
service redis_6379 stop
# 啟動
service redis_6379 start
Redis-cli 常用指令
- Redis命令文檔:https://www.redis.net.cn/order/
- 注意:key定義不能過長,不能過短:一般不超過1024個字節,太長不僅容易消耗內存,而且降低查找效率,太短會降低key的可讀性。
#進入Redis后檢查是否可以連接Redis服務
ping
# 查看所有的key
keys *
# 查看key 是否存在
EXISTS my_soul
#移除
move my_soul
#設置過期時間
EXPIRE my_soul 10 # 設置10秒鐘后過期
#查看剩余過期時間
ttl my_soul
#查看類型
type my_soul
#刪除key
del my_soul
# 切換 10 號數據庫
select 10
# 查看數據庫大小
DBSIZE
# 監視數據
watch mydata # 可實現樂觀鎖
unwatch
# 停止Redis
shutdown
# 清空所有緩存
flushall
auth 01Wyl62 flushall # 01Wyl62 為密碼
# 刪除指定數據庫內容,
select 2
flushdb
# 查看服務信息
info replication
# 集群配置,設置為從機(該機器ip:172.168.12.12)
slaveof 172.168.12.11 6379 # 172.168.12.11 為 主機
#集群信息
cluster info
#集群節點
cluster nodes
Redis-benchmark
- 壓力測試工具

浙公網安備 33010602011771號