Redis學習

Redis

1、NoSQL概述

NoSQL(NoSQL = Not Only SQL),意即「不只僅是SQL」,泛指非關係型數據庫,NoSQL能夠解決大規模集合多重數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題,包括超大規模數據的存儲,不少類型的數據存儲不須要固定的模式,無需多餘操做就能夠橫向擴展web

NoSQL數據庫種類繁多,可是一個共同的特色都是去掉關係數據庫的關係型特性。數據之間無關係,這樣就很是容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。redis

NoSQL數據庫都具備很是高的讀寫性能,尤爲是在大數據量下,很優秀。且NoSQL的Cache是記錄級的,是一種細粒度的Cache,因此NoSQL在這個層面上來講就要性能高不少了。算法

NoSQL無需事先爲要存儲的數據創建字段,隨時能夠存儲自定義的數據格式。而在關係數據庫裏,增刪字段很麻煩。sql

3V+3高shell

大數據時代的3V:海量Volume、多樣Variety、實時Velocity數據庫

互聯網需求的3高:高併發、高擴展、高性能緩存

NoSQL數據模型簡介:聚合模型:KV鍵值、Bson、列族、圖形安全

NoSQL四大分類服務器

  • KV鍵值網絡

    • 新浪:BerkeleyDB + redis
    • 美團:redis + tair
    • 阿里、百度:memcache + redis
  • 文檔型數據庫

    • CouchDB

    • MongoDB

      MongoDB是一個基於分佈式文件存儲的數據庫。由C++編寫,旨在爲WEB應用提供可擴展的高性能數據存儲解決方案

      MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係型數據庫當中功能最豐富,最像關係數據庫的。

  • 列存儲數據庫

    • Cassandra、Hbase
    • 分佈式文件系統
  • 圖關係數據庫

    • 不放圖形,放的是關係
    • 專一於構建關係圖譜
    • Neo4J,InfoGrid
  • 四者對比

分類 Examples舉例 典型應用場景 數據模型 優勢 缺點
鍵值(key-value) Tokyo、Oracle BDB 內容緩存、主要用於處理大量數據的高訪問負載,也用於一些日誌系統等等 key指向Value的鍵值對,一般hash table來實現 查找速度快 數據無結構化,一般只能被看成字符串或者二進制數據
列存儲數據庫 Cassandra、HBase、Riak 分佈式文件系統 以列簇存儲,將同一列數據存在一塊兒 查找速度快,可擴展性強,更容易進行細分 功能相對侷限
文檔型數據庫 CouchDB、MongoDB Web應用 key-Value對應的鍵值對,Value爲結構化數據 數據結構要求不嚴格,表結構可變,不須要先定義表結構 查詢性能不高,並且缺少統一的查詢語法
圖形數據庫 Neo4J 社交網絡,推薦系統等等 圖結構 利用圖結構相關算法 須要對整個圖計算才能得到須要的結果

分佈式數據庫中CAP原理

傳統的ACID:

  • A(Atomicity)原子性
  • C(Consistency)一致性
  • I(Isolation)獨立性
  • D(Durability)持久性

CAP:

  • C:Consistency(強一致性)
  • A:Availability(可用性)
  • P:Partition tolerance(分區容錯性)

CAP理論的核心:

一個分佈式系統不可能同時很好的知足一致性,可用性和分區容錯性這三個需求,最多隻能知足兩個!,所以,根據CAP原理將NoSQL數據庫分紅了知足CA原則、知足CP原則和知足AP原則三大類:

CA:單點集羣,知足一致性,可用性的系統,一般在可擴展性上不太強大

CP:知足一致性,分區容忍性的系統,一般性能不是特別高

AP:知足可用性,分區容忍性的系統,一般能夠對一致性要求低一些

But!!!,因爲當前的網絡硬件確定非出現延遲丟包等問題,因此 分區容忍性 是咱們必須須要實現的!因此咱們只能在一致性和可用性之間進行權衡,沒有NoSQL系統能同時保證這三點。

對於Web2.0網站來講,關係型數據庫的不少主要特性每每無用武之地!

數據庫事務一致性需求:

不少web實時系統並不要求嚴格的數據庫事務,對讀一致性要求很低,有些場合對寫一致性並不高。容許實現最終一致性。

數據庫的寫實時性和讀實時性需求:

對關係型數據庫來講,插入一條數據以後馬上查詢,是確定能夠讀出來這條數據的,可是對於不少Web應用來講,並不要求那麼高的實時性,比方說發一條消息以後,過幾秒乃至十幾秒以後,個人訂閱者纔看到這條動態是徹底能夠接受的。

對複雜的SQL查詢,特別是多表關聯查詢的需求:

任何大數據量的web系統,都很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免了這種狀況的產生。每每更多隻是單表的主鍵查詢,以及單表條件分頁查詢,SQL的功能被極大的弱化了。

BASE:

BASE就是爲了解決關係數據庫強一致性引發的問題而引發的可用性下降而提出的解決方案

BASE其實就是下面三個術語的縮寫:

基本可用(Basically Available)

軟狀態(Soft state)

最終一致(Eventually consistent)

它的思想是經過讓系統放鬆對某一時刻數據一致性的要求來換取系統總體伸縮性和性能上改觀。

分佈式系統+集羣:

分佈式系統(distributed system):

由多太計算機和通訊的軟件組件經過計算機網絡鏈接欸(本地網絡或廣域網)組成。分佈式系統是創建在網絡之上的軟件系統。正是由於軟件的特性,因此分佈式系統具備高度的內聚性和透明性。所以和分佈式系統之間的區別更多的在於高層軟件,而不是硬件。分佈式系統能夠應用在不一樣的平臺上...

簡單來講:

分佈式:不一樣的多臺服務器上面部署不一樣的服務模塊(工程),他們之間經過Rpc/Rmi之間通訊和調用,對外提供服務和組內協做。

集羣:不一樣的多臺服務器上面部署相同的服務模塊,經過分佈式調度軟件進行統一的調度,對外提供服務和訪問。

2、Redis概述

Redis就是一個使用C語言開發的數據庫,由於讀寫都在內存中進行,因此讀寫速度很是快,所以Redis被普遍應用於緩存方向

除了緩存,Redis也常常被用來作分佈式鎖,以及消息隊列

Redis提供了多種數據類型來支持不一樣的業務場景。Redis還支持事務、持久化、多種集羣方案

Redis有三個特色:

  • Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用
  • Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲
  • Redis支持數據的備份,即master-slave模式的數據備份

假如用戶第一次訪問數據庫中某些數據,這個過程就比較慢,畢竟是從硬盤中讀取的,可是,若用戶訪問的數據屬於高頻數據而且不會常常改變的話,那麼咱們就能夠很放心的將該用戶訪問的數據存在緩存中!

這樣就能夠保證用戶下一次再訪問這些數據的時候就能夠直接從緩存中獲取了,操做緩存就是直接操做操做系統,因此速度至關快(注意要保持數據庫和緩存中數據一致性)

3、Redis數據類型

3.1 Redis的五大數據類型

哪裏去得到redis常見數據類型操做命令

  • Redis鍵(key)

    keys *

    exists key的名字,判斷某個key是否存在

    move key db ---> 當前庫沒有了,被移除

    expire key 秒鐘:爲給定的key設置國企時間

    ttl key 查看還有多少秒過時, -1表示永不過時, -2表示已通過期

    type key 查看你的key是什麼類型

    1	DEL key
    該命令用於在 key 存在時刪除 key。
    2	DUMP key
    序列化給定 key ,並返回被序列化的值。
    3	EXISTS key
    檢查給定 key 是否存在。
    4	EXPIRE key seconds
    爲給定 key 設置過時時間,以秒計。
    5	EXPIREAT key timestamp
    EXPIREAT 的做用和 EXPIRE 相似,都用於爲 key 設置過時時間。 不一樣在於 EXPIREAT 命令接受的時間參數是 UNIX 時間戳(unix timestamp)。
    6	PEXPIRE key milliseconds
    設置 key 的過時時間以毫秒計。
    7	PEXPIREAT key milliseconds-timestamp
    設置 key 過時時間的時間戳(unix timestamp) 以毫秒計
    8	KEYS pattern
    查找全部符合給定模式( pattern)的 key 。
    9	MOVE key db
    將當前數據庫的 key 移動到給定的數據庫 db 當中。
    10	PERSIST key
    移除 key 的過時時間,key 將持久保持。
    11	PTTL key
    以毫秒爲單位返回 key 的剩餘的過時時間。
    12	TTL key
    以秒爲單位,返回給定 key 的剩餘生存時間(TTL, time to live)。
    13	RANDOMKEY
    從當前數據庫中隨機返回一個 key 。
    14	RENAME key newkey
    修改 key 的名稱
    15	RENAMENX key newkey
    僅當 newkey 不存在時,將 key 更名爲 newkey 。
    16	SCAN cursor [MATCH pattern] [COUNT count]
    迭代數據庫中的數據庫鍵。
    17	TYPE key
    返回 key 所儲存的值的類型。
  • Redis字符串(String)

    String類型是Redis最基本的類型,能夠理解成與Memcached如出一轍的類型,一個key對應一個value

    String類型是二進制安全的。便可以包含任何數據

    一個Redis中字符串value最多能夠是512M

    序號	命令及描述
    1	SET key value
    設置指定 key 的值
    2	GET key
    獲取指定 key 的值。
    3	GETRANGE key start end
    返回 key 中字符串值的子字符
    4	GETSET key value
    將給定 key 的值設爲 value ,並返回 key 的舊值(old value)。
    5	GETBIT key offset
    對 key 所儲存的字符串值,獲取指定偏移量上的位(bit)。
    6	MGET key1 [key2..]
    獲取全部(一個或多個)給定 key 的值。
    7	SETBIT key offset value
    對 key 所儲存的字符串值,設置或清除指定偏移量上的位(bit)。
    8	SETEX key seconds value
    將值 value 關聯到 key ,並將 key 的過時時間設爲 seconds (以秒爲單位)。
    9	SETNX key value
    只有在 key 不存在時設置 key 的值。
    10	SETRANGE key offset value
    用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始。
    11	STRLEN key
    返回 key 所儲存的字符串值的長度。
    12	MSET key value [key value ...]
    同時設置一個或多個 key-value 對。
    13	MSETNX key value [key value ...]
    同時設置一個或多個 key-value 對,當且僅當全部給定 key 都不存在。
    14	PSETEX key milliseconds value
    這個命令和 SETEX 命令類似,但它以毫秒爲單位設置 key 的生存時間,而不是像 SETEX 命令那樣,以秒爲單位。
    15	INCR key
    將 key 中儲存的數字值增一。
    16	INCRBY key increment
    將 key 所儲存的值加上給定的增量值(increment) 。
    17	INCRBYFLOAT key increment
    將 key 所儲存的值加上給定的浮點增量值(increment) 。
    18	DECR key
    將 key 中儲存的數字值減一。
    19	DECRBY key decrement
    key 所儲存的值減去給定的減量值(decrement) 。
    20	APPEND key value
    若是 key 已經存在而且是一個字符串, APPEND 命令將指定的 value 追加到該 key 原來值(value)的末尾。
  • Redis列表(List)

    Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素致使列表的頭部或者尾部,其底層實際是鏈表

    1	BLPOP key1 [key2 ] timeout
    移出並獲取列表的第一個元素, 若是列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
    2	BRPOP key1 [key2 ] timeout
    移出並獲取列表的最後一個元素, 若是列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
    3	BRPOPLPUSH source destination timeout
    從列表中彈出一個值,將彈出的元素插入到另一個列表中並返回它; 若是列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
    4	LINDEX key index
    經過索引獲取列表中的元素
    5	LINSERT key BEFORE|AFTER pivot value
    在列表的元素前或者後插入元素
    6	LLEN key
    獲取列表長度
    7	LPOP key
    移出並獲取列表的第一個元素
    8	LPUSH key value1 [value2]
    將一個或多個值插入到列表頭部
    9	LPUSHX key value
    將一個值插入到已存在的列表頭部
    10	LRANGE key start stop
    獲取列表指定範圍內的元素
    11	LREM key count value
    移除列表元素
    12	LSET key index value
    經過索引設置列表元素的值
    13	LTRIM key start stop
    對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間以內的元素都將被刪除。
    14	RPOP key
    移除列表的最後一個元素,返回值爲移除的元素。
    15	RPOPLPUSH source destination
    移除列表的最後一個元素,並將該元素添加到另外一個列表並返回
    16	RPUSH key value1 [value2]
    在列表中添加一個或多個值
    17	RPUSHX key value
    爲已存在的列表添加值
  • Redis集合(Set)

    Redis的Set是String類型的無序集合。它是經過HashTable實現的

    1	SADD key member1 [member2]
    向集合添加一個或多個成員
    2	SCARD key
    獲取集合的成員數
    3	SDIFF key1 [key2]
    返回第一個集合與其餘集合之間的差別。
    4	SDIFFSTORE destination key1 [key2]
    返回給定全部集合的差集並存儲在 destination 中
    5	SINTER key1 [key2]
    返回給定全部集合的交集
    6	SINTERSTORE destination key1 [key2]
    返回給定全部集合的交集並存儲在 destination 中
    7	SISMEMBER key member
    判斷 member 元素是不是集合 key 的成員
    8	SMEMBERS key
    返回集合中的全部成員
    9	SMOVE source destination member
    將 member 元素從 source 集合移動到 destination 集合
    10	SPOP key
    移除並返回集合中的一個隨機元素
    11	SRANDMEMBER key [count]
    返回集合中一個或多個隨機數
    12	SREM key member1 [member2]
    移除集合中一個或多個成員
    13	SUNION key1 [key2]
    返回全部給定集合的並集
    14	SUNIONSTORE destination key1 [key2]
    全部給定集合的並集存儲在 destination 集合中
    15	SSCAN key cursor [MATCH pattern] [COUNT count]
    迭代集合中的元素
  • Redis哈希(Hash)

    Redis Hash(哈希)是一個鍵值對集合,Redis Hash 是一個String類型的field和value的映射表,hash特別適合用於存儲對象,相似於Java中的Map<String,Object>

    1	HDEL key field1 [field2]
    刪除一個或多個哈希表字段
    2	HEXISTS key field
    查看哈希表 key 中,指定的字段是否存在。
    3	HGET key field
    獲取存儲在哈希表中指定字段的值。
    4	HGETALL key
    獲取在哈希表中指定 key 的全部字段和值
    5	HINCRBY key field increment
    爲哈希表 key 中的指定字段的整數值加上增量 increment 。
    6	HINCRBYFLOAT key field increment
    爲哈希表 key 中的指定字段的浮點數值加上增量 increment 。
    7	HKEYS key
    獲取全部哈希表中的字段
    8	HLEN key
    獲取哈希表中字段的數量
    9	HMGET key field1 [field2]
    獲取全部給定字段的值
    10	HMSET key field1 value1 [field2 value2 ]
    同時將多個 field-value (域-值)對設置到哈希表 key 中。
    11	HSET key field value
    將哈希表 key 中的字段 field 的值設爲 value 。
    12	HSETNX key field value
    只有在字段 field 不存在時,設置哈希表字段的值。
    13	HVALS key
    獲取哈希表中全部值。
    14	HSCAN key cursor [MATCH pattern] [COUNT count]
    迭代哈希表中的鍵值對。
  • Redis有序集合Zset(SortedSet:有序集合)

    與Set不一樣的是,每一個元素都會關聯一個double類型的分數,redis正是經過分數來爲集合中的成員進行從小到大的排序。zset的成員是惟一的,但分數(score)卻能夠重複

    1	ZADD key score1 member1 [score2 member2]
    向有序集合添加一個或多個成員,或者更新已存在成員的分數
    2	ZCARD key
    獲取有序集合的成員數
    3	ZCOUNT key min max
    計算在有序集合中指定區間分數的成員數
    4	ZINCRBY key increment member
    有序集合中對指定成員的分數加上增量 increment
    5	ZINTERSTORE destination numkeys key [key ...]
    計算給定的一個或多個有序集的交集並將結果集存儲在新的有序集合 key 中
    6	ZLEXCOUNT key min max
    在有序集合中計算指定字典區間內成員數量
    7	ZRANGE key start stop [WITHSCORES]
    經過索引區間返回有序集合指定區間內的成員
    8	ZRANGEBYLEX key min max [LIMIT offset count]
    經過字典區間返回有序集合的成員
    9	ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]
    經過分數返回有序集合指定區間內的成員
    10	ZRANK key member
    返回有序集合中指定成員的索引
    11	ZREM key member [member ...]
    移除有序集合中的一個或多個成員
    12	ZREMRANGEBYLEX key min max
    移除有序集合中給定的字典區間的全部成員
    13	ZREMRANGEBYRANK key start stop
    移除有序集合中給定的排名區間的全部成員
    14	ZREMRANGEBYSCORE key min max
    移除有序集合中給定的分數區間的全部成員
    15	ZREVRANGE key start stop [WITHSCORES]
    返回有序集中指定區間內的成員,經過索引,分數從高到低
    16	ZREVRANGEBYSCORE key max min [WITHSCORES]
    返回有序集中指定分數區間內的成員,分數從高到低排序
    17	ZREVRANK key member
    返回有序集合中指定成員的排名,有序集成員按分數值遞減(從大到小)排序
    18	ZSCORE key member
    返回有序集中,成員的分數值
    19	ZUNIONSTORE destination numkeys key [key ...]
    計算給定的一個或多個有序集的並集,並存儲在新的 key 中
    20	ZSCAN key cursor [MATCH pattern] [COUNT count]
    迭代有序集合中的元素(包括元素成員和元素分值)

Redis雖然說支持多線程,可是幾乎只用單線程,由於其性能瓶頸不在於CPU、而是主要在內存與網絡,只要是多線程就會存在死鎖、線程上下文切換,可能會影響性能!

Redis經過IO多路複用程序來監聽來自客戶端的大量鏈接,它會將感興趣的事件及類型(讀、寫)註冊到內核中並監聽每一個事件是否發生。

I/O 多路複用技術的使用讓 Redis 不須要額外建立多餘的線程來監聽客戶端的大量鏈接,下降了資源的消耗(和 NIO 中的 Selector 組件很像)。

Redis 經過一個叫作過時字典(能夠看做是hash表)來保存數據過時的時間。過時字典的鍵指向Redis數據庫中的某個key(鍵),過時字典的值是一個long long類型的整數,這個整數保存了key所指向的數據庫鍵的過時時間(毫秒精度的UNIX時間戳)。

5、Redis的持久化

RDB、AOF

RDB(Redis DataBase)

在指定的時間間隔內將內存中的數據集快照寫入磁盤,也就是行話講的Snapshot快照,它恢復時是將快照文件直接讀到內存裏。

Redis會單首創建一個子進程來進行持久化,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,在用這個臨時文件替換上次持久化好的文件。

整個過程當中,主進程是不進行任何IO操做的,這就確保了極高的性能。若不對數據敏感,且大規模數據恢復,則RDB比AOF更高效!

缺點就是:最後一次持久化的數據可能會丟失

image-20200903162957855

AOF(Append Only File)

以日誌的形式來記錄每一個寫操做,將Redis執行過的全部寫指令記錄下來(讀操做不記錄),只須追加文件但不能夠改寫文件,redis啓動之初會讀取該文件從新構造數據,換言之,redis重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工做

即:RDB持久化方式能夠在指定時間間隔對數據進行快照存儲,AOF持久化記錄每次對服務器寫的操做,但服務器重啓時會從新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操做到文件末尾,Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大!

同時開啓兩種持久化方式:redis重啓時會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。

6、緩存穿透

緩存穿透說簡單點就是大量請求的 key 根本不存在於緩存中,致使請求直接到了數據庫上,根本沒有通過緩存這一層

解決

  • 最基本的就是首先作好參數校驗,一些不合法的參數請求直接拋出異常信息返回給客戶端。好比查詢的數據庫 id 不能小於 0、傳入的郵箱格式不對的時候直接返回錯誤消息給客戶端等等。
  • 緩存無效 key
  • 布隆過濾器
相關文章
相關標籤/搜索