**redis數據庫基礎**
1、redis簡介
2、redis數據操作
3、redis持久化
4、redis其他知識
**redis簡介**
**1.1、簡介**
Redis是C語言開發的一個開源高性能鍵值對的內存數據庫,可以用來做數據庫、緩存、消息中間件等場景,是一種NoSQL(not-only sql,非關系型數據庫)的數據庫。
**1.2、特點**
* 優秀的性能,數據是存儲在內存中,讀寫速度非常快,可支持并發10W QPS
* 單線程單進程,
使用非阻塞I/O,
多路復用I/O模型
* 可作為分布式鎖
* 支持五種數據類型
* 支持數據持久化到磁盤
* 可以作為消息中間件使用,支持消息發布及訂閱
* 默認端口6379,16個數據庫,默認0庫開始
* **1.3、服務端和客戶端**
**服務端:**
* 服務器端的命令為redis-server
可以使用help查看幫助文檔
~~~
redis-server --help
~~~
* 推薦使用服務的方式管理redis服務
啟動
~~~
sudo service redis start
~~~
停止
~~~
sudo service redis stop
~~~
重啟
~~~
sudo service redis restart
~~~
**客戶端:**
* 客戶端的命令為redis-cli
可以使用help查看幫助文檔
~~~
redis-cli --help
~~~
運行測試命令
~~~
ping
~~~
切換數據庫(數據庫沒有名稱,默認有16個,通過0-15來標識)
~~~
select 1
~~~

**redis數據操作**
PART 02
redis是key-value的數據結構,每條數據都是一個鍵值對,鍵的類型是字符串(鍵不能重復),值的類型分為五種:
* 字符串string
* 哈希hash
* 列表list
* 集合set
* 有序集合zset
**2.1、字符串string**
* string是redis最基本的類型
* 最大能存儲512MB數據
* string類型是二進制安全的,可以存儲任何數據,比如數字、圖片等
**增加、修改**
~~~
# 如果設置的鍵不存在則為添加,如果設置的鍵已經存在則修改
~~~
**獲取**
~~~
根據鍵獲取值,如果不存在此鍵則返回nil
~~~
**鍵命令(查找、刪除)**
~~~
查找鍵,參數通配符查找
~~~
**2.2、哈希hash**
* hash用于存儲對象,對象的結構為屬性、值
* 值的類型為string
**增加、修改**
~~~
設置單個屬性
~~~
**獲取**
~~~
獲取指定鍵所有的屬性
~~~
**刪除**
~~~
刪除整個hash鍵及值,使用del命令
~~~
**2.3、列表list**
* 列表的元素類型為string
* 按照插入順序排序
**增加**
~~~
在左側插入數據
~~~
**修改
**
~~~
設置指定索引位置的元素值
~~~
**獲取**
~~~
返回列表里指定范圍內的元素
~~~
**刪除**
~~~
刪除指定元素
~~~
**2.4、集合set**
* 無序集合
* 元素為string類型
* 元素具有唯一性,不重復
* 對于集合沒有修改操作
**增加**
~~~
#添加元素
~~~
**獲取**
~~~
返回所有的元素
~~~
**刪除**
~~~
刪除指定元素
~~~
**2.5、有序集合zset**
* sorted set,有序集合
* 元素為string類型
* 元素具有唯一性,不重復
* 每個元素都會關聯一個double類型的score,表示權重,通過權重將元素從小到大排序
* 沒有修改操作
**增加**
~~~
添加
~~~
**獲取**
~~~
返回指定范圍內的元素
~~~
**刪除**
~~~
刪除指定元素
~~~

**redis持久化**
PART 03
**3.1、redis持久化方式**
redis是一個內存數據庫,一旦斷電或服務器進程退出,內存數據庫中的數據將全部丟失,所以需要redis持久化。
redis持久化就是把數據保存在磁盤上,利用永久性存儲介質將數據保存,在特定的時間將保存的數據進行恢復的工作機制。
redis提供兩種持久化機制:
* RDB:存儲數據結果,關注點在數據
* AOF:存儲操作過程,關注點在數據的操作過
程
**3.2、RDB**
* 原理:將Reids在內存中的數據庫記錄定時dump到磁盤上的RDB持久化,直接把內存中的數據保存到一個 dump 的文件中。
* 開啟RDB持久化方式:
客戶端可以通過向Redis服務器發送save或bgsave命令讓服務器生成rdb文件,或者通過服務器配置文件指定觸發RDB條件。
~~~
#?同步數據到磁盤上命令
~~~

由于redis的單進程單線程特性,當客戶端向服務器發送save命令請求進行持久化時,服務器會阻塞save命令之后的其他客戶端的請求,直到數據同步完成。如果數據量太大,同步數據會執行很久,而這期間redis服務器也無法接收其他請求,所以,最好不要在生產環境使用save命令。
~~~
#?異步保存數據集到磁盤上
~~~

當客戶端發服務發出bgsave命令時,redis服務器主進程會forks一個子進程來數據同步問題,在將數據保存到rdb文件之后,子進程會退出。所以,與save命令相比,redis服務器在處理bgsave采用子線程進行IO寫入,而主進程仍然可以接收其他請求,但forks子進程是同步的,所以forks子進程時,一樣不能接收其他請求,這意味著,如果forks子進程花費的時間太久(一般是很快的),bgsave命令仍然有阻塞其他客戶的請求的情況發生。
~~~
#?服務器配置自動觸發
~~~
這種通過服務器配置文件觸發RDB的方式,與bgsave命令類似,達到觸發條件時,會forks一個子進程進行數據同步,不過最好不要通過這種方式來觸發RDB持久化,因為設置觸發的時間太短,則容易頻繁寫入rdb文件,影響服務器性能,時間設置太長則會造成數據丟失。
* RDB文件:
執行同步數據到磁盤操作后,生成臨時rdb文件,并寫入數據;完成數據寫入,用臨時文代替代正式rdb文件,刪除原來的rdb文件。RDB默認生成的文件名為dump.rdb(可通過配置文件修改RDB默認文件名)。
**3.3、AOF**
* 原理:將Reids的操作日志以追加的方式寫入文件,把所有的對 Redis的服務器進行修改的命令都存到一個文件里,保存的是命令的集合。
* 開啟AOF持久化方式:

與RDB存儲某個時刻的快照不同,AOF持久化方式會記錄客戶端對服務器的每一次寫操作命令,并將這些寫操作以Redis命令追加保存到以后綴為aof文件的末尾,在Redis
服務器重啟時,會加載并運行aof文件的命令,以達到恢復數據的目的。
Redis默認不開啟AOF持久化方式,需要在配置文件中開啟并進行更加詳細的配置,如下面的redis.conf文件:
~~~
# 開啟aof機制
~~~
* 三種寫入策略:
1. always
:
客戶端的每一個寫操作都保存到aof文件,這種策略很安全,但是每個寫請注都有IO操作,所以也很慢。
2. everysec
:
appendfsync的默認寫入策略,每秒寫入一次aof文件,因此,最多可能會丟失1s的數據。
3. no:Redis服務器不負責寫入aof,而是交由操作系統來處理什么時候寫入aof文件。更快,但也是最不安全的選擇,不推薦使用。
**3.4、兩者區別&優劣勢**
區別:
* RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲。
* AOF持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。
優劣勢:
* 如果非常關心你的數據,但仍然可以承受數分鐘內的數據丟失,那么可以額只使用 RDB持久化。
* AOF將Redis 執行的每一條命令追加到磁盤中,處理巨大的寫入會降低Redis的
性能。
* 數據庫備份和災難恢復:定時生成 RDB 快照非常便于進行數據庫備份,并且 R
DB恢復數據集的速度也要比 AOF 恢復的速度快。
(Redis 支持同時開啟 RDB 和 AOF,系統重啟后,Redis 會優先使用 AOF 來恢復數據,這樣丟失的數據會最少。)

**redis其他知識**
PART 04
**4.1、主從模式**
* 原理:
將一臺redis服務器的數據,復制到其他的redis服務器,前者稱為主節點(master/leader,主節點不用配置,redis默認單機就是主節點),后者稱為從節點(slave/follower);數據的復制是單向的,只能由主節點到從節點。master以寫為主,slave以讀為主。主從復制,讀寫分離。
* 作用:
數據冗余(實現數據的熱備份)、故障恢復、負載均衡(讀寫分離等操作,可以減緩服務器壓力,架構中經常使用)、高可用基石(它是哨兵與集群能夠實施的基礎)、集群模式的最低配置應該是一主二從,三臺服務器。
* 主從復制步驟
當slave啟動成功連接到master后會發送一個sync同步命令,master接到命令,啟動后臺的存盤進程,同時收集所有用于修改數據集命令,在后臺進程執行完畢后,master將傳送整個數據文件(RDB文件)到slave,并且完成一次完全同步(全量復制);只要是重新連接master,全量復制將會被自動執行,數據一定可以在從機中看到。
全量復制?—— slave服務在接收到數據庫文件數據后,將其存盤并加載到內存中;
增量復制?—— master繼續將新的所有收集到的修改命令依次傳給slave,完成同步;

~~~
# 主從復制只需要在從機中配置,命令如下:
~~~
**4.2、哨兵模式**
* 原理:
哨兵模式就是自動選取主機的方法,哨兵模式是一種特殊的模式,redis提供了哨兵的命令,它是一個獨立的進程,原理是哨兵通過發送命令,等待Redis服務器響應,從而監控運行的多個redis實例。
* 哨兵模式的由來:
主從復制會存在如下問題:一旦主節點宕機,從節點晉升為主節點,同時需要修改應用方的主節點地址,還需要命令所有從節點去復制新的主節點,整個過程需要人工干預。
* 哨兵模式的作用:
1. 通過發送命令,令redis服務器返回運行狀態,包括主服務器與從服務器;
2. 當哨兵檢測到master宕機,會自動將slave切換到master,然后通過發布訂閱模式通知其他從服務器,修改配置文件,切換主機。
* 哨兵的架構模式如下:

可以執行以下四個任務:
* 監控:不斷檢查主服務器和從服務器是否正常運行。
* 通知:當被監控的某個 Redis 服務器出現問題,Sentinel 通過 API 腳本向管理員或者其他應用程序發出通知。
* 自動故障轉移:當主節點不能正常工作時,Sentinel 會開始一次自動的故障轉移操作,它會將與失效主節點是主從關系的其中一個從節點升級為新的主節點,并且將其他的從節點指向新的主節點,這樣人工干預就可以免了。
* 配置提供者:在 Redis Sentinel 模式下,客戶端應用在初始化時連接的是 Sentinel 節點集合,從中獲取主節點的信息。
**4.3、集群模式**
* 原理:
哨兵模式雖然基本已經可以實現高可用、讀寫分離;但是在這種模式下每臺 Redis 服務器都存儲相同的數據,很浪費內存,所以在redis3.0上加入了?Cluster?集群模式,實現了 Redis 的分布式存儲,也就是說每臺 Redis 節點上存儲不同的內容。
* 集群的配置:
集群部署至少需要3臺以上的master節點,最好使用3主3從6個節點的模式;這里的 6 臺 redis 兩兩之間并不是獨立的,每個節點都會通過集群總線(cluster bus),與其他的節點進行通信。所有的redis節點彼此互聯,內部使用二進制協議優化傳輸速度和帶寬;節點的 fail 是通過集群中超過半數的節點檢測失效時才生效;客戶端與 Redis 節點直連,不需要中間代理層,客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可。

* 工作方式:
在 Redis 的每一個節點上,都有兩個東西,一個是插槽(slot),它的取值范圍是:0-16384。還有一個就是cluster,可以理解為是一個集群管理的插件。當我們的存取的 Key到達的時候,Redis 會根據crc16的算法得出一個結果,然后把結果對16384求余數,這樣每個 key 都會對應一個編號在0-16384 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作。
**4.4、reids的雪崩&穿透&擊穿**
**緩存雪崩**
* 定義:
redis緩存中大量的key同時失效,此時又剛好有大量的請求打進來,直接打到數據庫層,造成數據庫阻塞甚至宕機。

* 解決辦法:
1. 讓redis數據永不過期,這種方式最可靠的,最安全的但是占空間,內存消耗大,并且不能保持數據最新,所以需要根據具體的業務邏輯來做
2. 將緩存失效時間分散開,比如每個key的過期時間都是隨機的,防止同一時間大量數據過期的現象發生,就不會出現同一時間全部請求都落在數據庫。
3. 因為redis宕機導致緩存雪崩的問題,可以啟動服務熔斷機制,暫停業務應用對緩存服務的訪問,直接返回錯誤,但是暫停了業務應用訪問緩存系統,全部業務都無法正常的工作
4. 創造redis集群,對數據庫進行讀寫分離
**緩存穿透**
* 定義:
指查詢一個緩存和數據庫都不存在的數據,導致盡管數據不存在但是每次都會到數據庫查詢。在訪問量大時可能DB就會掛掉。如果有人利用不存在的key頻繁攻擊,則這就形成了漏洞。

* 解決辦法:
1. 如果一個查詢返回的數據為空,我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。
2. 接口層增加校驗,用戶鑒權,id做基礎校驗。
3. 采用布隆過濾器,將所有可能存在的數據hash到一個足夠大的bitmap中。
布隆過濾器:類似于HashSet,可以快速判斷一個元素在集合中是否存在,應用場景:快速判斷一個元素是否在某容器內,不存在直接返回。(關鍵點在于hash算法和容器大小。)
**緩存擊穿**
* 定義:
擊穿與雪崩的不同在于緩存key失效的量級上。擊穿是對于單個key值(熱點數據)的緩存失效過期,雪崩則是大面積key同時失效。

* 解決辦法:
1. 若緩存數據基本不會發生更新,則可嘗試將熱點數據設置為永不過期。
2. 若緩存的數據更新不頻繁,且緩存刷新的整個流程耗時較少的情況下,則可以采用基于Redis、zookeeper 等分布式中間件的分布式互斥鎖,或者本地互斥鎖以保證僅少量的請求能請求數據庫并重新構建緩存,其余線程則在鎖釋放后能訪問到新緩存。
3. 若緩存的數據更新頻繁或者在緩存刷新的流程耗時較長的情況下,可以利用定時線程在緩存過期前主動地重新構建緩存或者延后緩存的過期時間,以保證所有的請求能一直訪問到對應的緩存。
- 后端
- composer
- composer配置國內鏡像
- composer安裝及設置2
- PHP
- 貝塔SG11加密
- 申請KEY
- 開始加密
- php 中連接tcp服務的三種方式
- php websocket 教程
- editor內容轉換數組
- 使用正則判斷中文維吾爾文
- PHP常用函數總結
- 常用助手函數
- 通過Imagick把pdf轉換圖片
- 維吾爾語基本區轉換擴展區
- php GD庫生成一個由文字和圖片生成新的圖片
- aes加密
- php數組函數 -- array_column,array_multisort 實現二維數組排序
- PHP操作Excel
- php更新內容
- 輔助查詢(*)
- 【時間】操作
- 時間函數例子
- Date/Time 函數(不包含別名函數)
- php網絡相關
- HTTP請求的返回值含義說明
- 使用php語言開發一個類似數據庫操作的文件表類
- pinyin
- 維吾爾語基本區轉換擴展區(2)
- php獲取當前環境的信息
- laravel
- laravel 隊列的使用
- laravel 自定義助手函數
- laravel seeder的使用
- laravel項目從git下載命令
- laravel 多個數據庫配置
- laravel 填充假數據
- laravel 動態路由
- laravel 自定義 validate 響應
- laravel 創建追加字段的模擬訪問器
- laravel 線上環境的數據庫更改或添加字段
- laravel 模型查詢按照whereIn排序
- laravel 使用 workerman 通過TCP 文件傳輸功能
- laravel api Header添加Accept頭
- Laraval IDE 自動補全插件 laravel-ide-helper
- laravel 網站后臺
- laravel 設置路由
- laravel-第三方composer包
- laravel 開發技巧
- laravel 昨天,今天時間
- 使用寶塔計劃任務啟動laravel調度器
- laravel結合workerman第二節
- Laravel - 上傳多個文件
- 查詢聊天好友列表
- 事件系統 event, listener
- laravel 安裝 laravel-modules
- 自定義求看守器-toekn
- laravel限流
- 使用 Laravel api Resource 類時自定義分頁信息
- Laravel php artisan命令大全
- 驗證器
- workerman 創建wss服務
- 架構師必須知道的26項PHP安全實踐
- python
- Python讀取文件代碼塊已經備好,用的時候光拿(建議收藏)
- Python常用庫大全
- api 簽名驗證
- git
- git命令
- 十分鐘學會git基礎
- Git代碼同時上傳到GitHub和Gitee(碼云)
- Git - 多人協同開發利器,團隊協作流程規范與注意事項
- 刪除遠程倉庫的文件
- github查詢方法
- 錯誤
- 解除項目git版本控制
- linux
- sentos安裝supervisor
- PHP怎么守護進程運行php腳本
- 600條最強Linux命令總結
- centos開啟防火墻、開放指定端口
- 前端
- vue
- vue2發布之前的config簡單配置
- vue2安裝scss命令
- vue2父子組件之間雙向數據綁定
- 國際化雙語--安裝VueI18n
- vue3-setup 組件傳參(defineProps、defineEmits、defineExpose
- Vue3 新寫法速覽:十分鐘內輕松get
- 關于vue的外連接
- watch講解
- computed
- webpack 打包后生成很多小文件怎么優化?
- vue2 vue.config.js常見配置和打包部署測試
- 小程序
- 小程序長期訂閱消息
- 小程序自定義TabBar后如何實現keep-alive
- 收藏的html和css和js
- CSS 省略號(單行省略號、多行省略號)
- UyghurInput_a.js
- font.css
- 漂亮按鈕樣式
- clock.html
- css
- scroll css樣式
- CSS流動布局-頁面自適應
- css grid布局
- 禁止wap頁面調整字體大小
- CSS @media 和 min-width/max-width
- 網站變灰是怎么實現的
- 瀑布流實現方式
- javascript
- SortableJS拖動排序
- wondow scroll滾動到上邊
- 原生js插入HTML元素
- Konva.js —— 像操作DOM一樣操作canvas
- 通過canvas合并倆個圖片
- js scroll更多加載
- js 實現復制功能
- js判斷安卓和蘋果或者微信
- 瀏覽器打開控制臺禁止
- 原生js一些dom操作
- js http客戶端集合
- fetch
- axios
- canvas 點鐘
- layer dialog
- jquery 和 laravel ajax全局配置
- layui 獲取select的自定義參數
- konva.js中文開發文檔
- js 大文件分片上傳
- js監聽網絡狀態實現斷網重連后自動刷新頁面
- js生成video縮略圖
- JS獲取當前系統電量情況
- uniapp
- uni-app swiper數量過多時卡頓優化方案
- uniapp 帖子集合
- 微信wap
- wap分享朋友和朋友圈
- wap 手機頁面微信支付
- JsSdk微信公眾號支付
- 通用各種小知識
- 正則表達式
- JS正則匹配過濾字符串中的html標簽及html標簽內的內容
- 判斷維吾爾文輸入
- 正則表達式符號
- 正則表達式練習
- 百度網盤不限速下載助手
- 解決VSCode下載慢或下載失敗的問題
- 性能測試 使用Apache的ab測試工具
- nginx從入門到精通
- nginx
- Nginx 是怎么禁止訪問php的 ?
- 寶塔面板
- supervisor
- 卸載寶塔
- redis
- redis實用筆記
- redis入門到精通
- phpredis
- redis數據庫基礎
- PHP對Redis的基本操作
- ffmpeg
- 合并多個音視
- 獲取音視時長
- FFmpeg視頻處理入門教程(新手必看)
- 外連接
- 安裝
- PHP基于ffmpeg實現轉換視頻,截圖及生成縮略圖的方法
- Linux安裝ffmpeg
- docker
- 服務實現
- docker基本命令
- rewrite筆記
- 別人筆記鏈接
- 計算機常用知識
- 二進制1-10
- 斐波那契數列
- mysql
- 高性能高可用的MySQL,得從各種規范開始
- 讀寫分離配置
- 重要外連接,前端/ 后端/數據庫等等
- 關于程序必須收藏的文章鏈接集合
- markdown
- 一篇文章講清楚markdown