后台开发人员面试内容——Redis非关系数据库(三)
主要介紹:Redis概念,特點,數據存儲類型,持久化方式及其優缺點,通訊協議,五種架構模式,緩存穿透、緩存雪崩、緩存并發及其的解決辦法
關系數據庫:
關系型數據庫最典型的數據結構是表,由二維表及其之間的聯系所組成的一個數據組織
優點:
1、易于維護:都是使用表結構,格式一致;
2、使用方便:SQL語言通用,可用于復雜查詢;
3、復雜操作:支持SQL,可用于一個表以及多個表之間非常復雜的查詢。
缺點:
1、讀寫性能比較差,尤其是海量數據的高效率讀寫;
2、固定的表結構,靈活度稍欠;
3、高并發讀寫需求,傳統關系型數據庫來說,硬盤I/O是一個很大的瓶頸。
?
非關系型數據庫:
嚴格上不是一種數據庫,應該是一種數據結構化存儲方法的集合,可以是文檔或者鍵值對等。
優點:
1、格式靈活:存儲數據的格式可以是key,value形式、文檔形式、圖片形式等等,文檔形式、圖片形式等等,使用靈活,應用場景廣泛,而關系型數據庫則只支持基礎類型。
2、速度快:nosql可以使用硬盤或者隨機存儲器作為載體,而關系型數據庫只能使用硬盤;
3、高擴展性;
4、成本低:nosql數據庫部署簡單,基本都是開源軟件。
缺點:
1、不提供sql支持,學習和使用成本較高;
2、無事務處理;
3、數據結構相對復雜,復雜查詢方面稍欠。
?
Redis 是速度非常快的非關系型(NoSQL)內存鍵值數據庫,
一、特點:
1.Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用,若沒有進行持久化操作,Redis服務器關閉后,數據庫中變動的數據會消失
2.可以存儲鍵和五種不同類型的值之間的映射。
鍵的類型只能為字符串,值支持五種數據類型:字符串(String)、列表(list)、集合(set)、散列表(hash)、有序集合(zset)。
優勢:
1.性能極高?– Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
2.豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
3.原子 – Redis的所有操作都是原子性的,意思就是要么成功執行要么失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過MULTI和EXEC指令包起來。
4.豐富的特性?– Redis還支持 publish/subscribe, 通知, key 過期等等特性
??
二、使用方法:
下載解壓到Redis目錄:
1.在Redis目錄下啟動服務器及它的配置文件
redis-server.exe redis.windows.conf
?
2.開啟客戶端使用
redis-cli.exe -h 127.0.0.1 -p 6379
?
3.鍵值對使用
redis默認選擇的是0數據庫
String類型使用方法
set?mykey 111——設置鍵值對
get?mykey——獲取鍵key對應的value
del? mykey——刪除鍵,成功輸出(integer) 1
exists?mykey——檢查是否存在key,沒有輸出(integer)?0
keys? myk*——查找所有符合模式的key集合,key *?可以查找所有當前數據庫下的key對應的value
move mykey 1——將key移動到1數據庫
rename?mykey?newkey——修改key的名稱
type mykey——返回key對應的value的類型
getrange?mykey 0 2 ——返回mykey的value的前三個字符
mget?key1, key2....——得到多個key對應的value
mset?key1?value1?key2?value2——同時設置多個key-value對
strlen?mykey——返回key對應value長度
?
Hash類型使用方法——每個key對應的是一個對象
Redis hash 是一個string類型的field和value的映射表,hash特別適合用于存儲對象。
Redis 中每個 hash 可以存儲 232?- 1 鍵值對(40多億)
?
hmset student name "likui" grade 3.56 class "1203"——設置student對象屬性
hgetall student ——得到student對象的所有屬性
設置對象屬性和得到指定對象屬性的方法
hexists?student?name——檢查student的name屬性是否存在
hkeys?student——獲取所有student的字段
hlen?key——獲取哈希表key的長度
hmget?key?field1,field2...——獲取哈希表key對應的字段值
hmset? key?field1 value2 field2?value2——設置hash表key對應屬性值
獲取所有hash表中的值
?
List類型使用方法——相對于是一個棧(stack)
Redis列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)
?
lpush?list 1,2,....——往list集合中加入元素
lset list 0 1——設置list集合指定位置值
lindex list 0——獲取集合中指定位置元素
lpop list——移除并獲取列表中第一個元素
?
Set類型使用方法——無序不重復結合
Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現重復的數據
Redis 中集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是 O(1)
?
sadd key value——往set集合中添加值
scard key——獲取set集合成員數
smember?key——返回set集合所有值
?
zset類型使用方法——有序不重復集合
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序
有序集合的成員是唯一的,但分數(score)卻可以重復
?
zadd?key?grade?value
zadd?key?grade?value2 ,往zset中添加元素方式,grade可以重復,但是value不能
zrank?key?value——返回zest中key指定元素索引
zrem?key?value——移除zset中指定元素
zscore?key?value——返回zset中指定元素分數值
4.操作數據庫語句
select?數字? 切換到指定數據庫
?
三、Redis進行持久化的方式
由于Redis的數據都存放在內存中,如果沒有配置持久化,redis重啟后數據就全丟失了,于是需要開啟redis的持久化功能,將數據保存到磁盤上,當redis重啟后,可以從磁盤中恢復數據
1. RDB持久化(Redis?DataBase):?在指定的時間間隔內將內存中的數據集快照寫入磁盤。實際操作過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲
2. AOF持久化 (append only file): 原理是將Reids的操作日志以追加的方式寫入文件。 AOF持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,讀操作不會記錄, 在服務器啟動時,通過重新執行這些命令來還原數據集
?
具體持久化方式:
1)找到conf配置文件,打開它
2)在文件中搜索save
Redis會將數據集的快照dump到dump.rdb文件中。此外,我們也可以通過配置文件來修改Redis服務器dump快照的頻率,在打開6379.conf文件之后,我們搜索save,可以看到下面的配置信息:
save 900 1????????????? #在900秒(15分鐘)之后,如果至少有1個key發生變化,則dump內存快照。
save 300 10??????????? #在300秒(5分鐘)之后,如果至少有10個key發生變化,則dump內存快照。
save 60 10000??????? #在60秒(1分鐘)之后,如果至少有10000個key發生變化,則dump內存快照。
3)AOF持久化配置
在Redis的配置文件中存在三種同步方式,它們分別是:
# If unsure, use "everysec".
# appendfsync always??#每次有數據修改發生時都會寫入AOF文件。
appendfsync everysec??#每秒鐘同步一次,該策略為AOF的缺省策略。
# appendfsync no??#從不同步。高效但是數據不會被持久化。
4)最后一定要在客戶端使用shutdown命令關閉服務器
?
四、RDB和AOF持久化特點:
RDB優點:
1.整個Redis數據庫將只包含一個文件,這對于文件備份而言是非常完美的
2.對于災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上
3.性能最大化。對于Redis的服務進程而言,在開始持久化時,它唯一需要做的只是fork出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行IO操作了
4.相比于AOF機制,如果數據集很大,RDB的啟動效率會更高
RDB缺點:
1.一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失
2.如果當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是1秒鐘
AOF優點:
1.這個機制可以帶來更高的數據安全性,即數據持久性。?每次修改后,操作都會被寫入到日志文件中去,采取的同步機制在寫入過程中即使出現宕機現象,也不會破壞日志文件中已經存在的內容
2.AOF包含一個格式清晰、易于理解的日志文件用于記錄所有的修改操作, 我們也可以通過該文件完成數據的重建
AOF缺點:
1.對于相同數量的數據集而言,AOF文件通常要大于RDB文件。RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快
2.根據同步策略的不同,AOF在運行效率上往往會慢于RDB
? ? ? 選擇方面,如果系統追求高性能,可以采用RDB持久化方式,若是追求安全性,查看服務器操作日志、防止系統宕機情況發生的話采取AOF持久化方式較好
?
五、Redis通訊協議( Redis Serialization Protocol,RESP)
RESP 是redis客戶端和服務端之前使用的一種通訊協議,?基于請求-響應的模式
RESP 的特點:實現簡單、快速解析、可讀性好
RESP有五種最小的單元類型,單元結束時統一加上回車換行符號\r\n
(+) 表示一個正確的狀態信息,具體信息是當前行+后面的字符。
(-) 表示一個錯誤信息,具體信息是當前行-后面的字符。
(*) 表示消息體總共有多少行,不包括當前行,*后面是具體的行數。
($)表示下一行數據長度,不包括換行符長度\r\n,)表示下一行數據長度,不包括換行符長度\r\n,后面則是對應的長度的數據。
(:) 表示返回一個數值,:后面是相應的數字節符。
可以通過wireshark軟件查看
set?demo 123456? //MSEP進行處理*3\r\n #消息一共有三行$3\r\n #第一行有長度為3set\r\n #第一行的消息$4\r\n #第二行長度為4demo\r\n #第二行的消息$6\r\n #第三行長度為6123456\r\n #第三行的消息+OK\r\n #操作成功?
六、Redis有哪些架構模式?
1.單機版。多個客戶端訪問一個服務器,多用于在本地運行的程序,服務器在本機上
特點:
簡單;內存容量有限、處理能力有效、無法高可用
2.主從復制。 Redis 的復制(replication)功能允許用戶根據一個 Redis 服務器來創建任意多個該服務器的復制品,其中被復制的服務器為主服務器(master),而通過復制創建出來的服務器復制品則為從服務器(slave)。 只要主從服務器之間的網絡連接正常,主從服務器兩者會具有相同的數據,主服務器就會一直將發生在自己身上的數據更新同步 給從服務器,從而一直保證主從服務器的數據相同。
特點:
1、master/slave 角色
2、master/slave 數據相同
3、降低 master 讀壓力在轉交給從庫
3.哨兵(sentinel)。sentinel 是一個分布式系統中監控 redis 主從服務器, 并在主服務器下線時自動進行故障轉移
特點:
1)監控(Monitoring):Sentinel? 會不斷地檢查你的主服務器和從服務器是否運作正常。
2)提醒(Notification):當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
3)自動故障遷移(Automatic failover): 如果Master 異常,則會進行Master-slave 轉換,將其中一個Slave作為Master。
缺點:切換需要時間,會丟失數據
4.集群(代理型):
特點:
1)多種 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
2)支持失敗節點自動刪除
3)后端 Sharding 分片邏輯對業務透明,業務方的讀寫方式和操作單個 Redis 一致
缺點:增加了新的 proxy,需要維護其高可用。
?
5.集群( redis-cluster): 采用無中心結構,每個節點保存數據和整個集群狀態,每個節點都和其他所有節點連接
特點:
1、無中心架構(不存在哪個節點影響性能瓶頸),少了 proxy 層。
2、數據按照 slot 存儲分布在多個節點,節點間數據共享,可動態調整數據分布。
3、可擴展性,可線性擴展到 1000 個節點,節點可動態添加或刪除。
4、高可用性,部分節點不可用時,集群仍可用。通過增加 Slave 做備份數據副本
5、實現故障自動 failover,節點之間通過 gossip 協議交換狀態信息,用投票機制完成 Slave到 Master 的角色提升。
缺點:
1、資源隔離性較差,容易出現相互影響的情況。
2、數據通過異步復制,不保證數據的強一致性
?
七、什么是緩存穿透?如何避免?什么是緩存雪崩?何如避免?緩存并發問題?
Redis一般用于充當緩存數據庫功能?,一般的緩存系統, 數據查詢先進行緩存查詢,如果key不存在或者key已經過期,再對數據庫進行查詢,并把查詢到的對象,放進緩存,如果數據庫查詢對象為空,則不放進緩存
1.緩存穿透
惡意用戶模擬請求很多緩存中不存在的數據,由于緩存中都沒有,導致這些請求短時間內直接落在了數據庫上,導致數據庫異常。這就叫做緩存穿透。
2.如何避免穿透 ?
1)對查詢結果為空的情況也進行緩存:緩存時間設置短一點,或者該key對應的數據insert了之后清理緩存。
2)?加鎖( synchronized,lock):key獲取value值為空時,對后端數據庫操作語句加鎖鎖上,從數據庫中load數據后再釋放鎖
3.緩存雪崩
當緩存服務器重啟或者大量緩存集中在某一個時間段失效,在失效的時候,大量的請求會給數據庫帶來很大壓力。導致系統崩潰
4.如何避免?
1)加鎖:通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。
2)二級緩存:A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置為短期,A2設置為長期
3)設置不同過期時間:不同的key,設置不同的過期時間,讓緩存失效的時間點盡量均勻。
5.緩存并發問題?
多個redis的client同時set key引起的并發問題, redis自身就是單線程操作,多個client并發操作,按照先到先執行的原則,先到的先執行,其余的阻塞。?將這些操作放在隊列中使其串行化,一個一個的進行執行,或者進行加鎖
?
總結
以上是生活随笔為你收集整理的后台开发人员面试内容——Redis非关系数据库(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery ajax使用方法
- 下一篇: MySQL乐观锁、共享锁、排他锁、行锁、