1:NoSql入門和概述
1)入門概述
A、網際網路時代背景下大機遇,為什麼用nosql
單機MySQL的美好年代
在90年代,一個網站的通路量一般都不大,用單個資料庫完全可以輕松應付。
在那個時候,更多的都是靜态網頁,動态互動類型的網站不多。
上述架構下,我們來看看資料存儲的瓶頸是什麼?
- 資料量的總大小 一個機器放不下時
- 資料的索引(B+ Tree)一個機器的記憶體放不下時
- 通路量(讀寫混合)一個執行個體不能承受
如果滿足了上述1 or 3個,進化......
Memcached(緩存)+MySQL+垂直拆分
後來,随着通路量的上升,幾乎大部分使用MySQL架構的網站在資料庫上都開始出現了性能問題,web程式不再僅僅專注在功能上,同時也在追求性能。程式員們開始大量的使用緩存技術來緩解資料庫的壓力,優化資料庫的結構和索引。開始比較流行的是通過檔案緩存來緩解資料庫壓力,但是當通路量繼續增大的時候,多台web機器通過檔案緩存不能共享,大量的小檔案緩存也帶了了比較高的IO壓力。在這個時候,Memcached就自然的成為一個非常時尚的技術産品。

Memcached作為一個獨立的分布式的緩存伺服器,為多個web伺服器提供了一個共享的高性能緩存服務,在Memcached伺服器上,又發展了根據hash算法來進行多台Memcached緩存服務的擴充,然後又出現了一緻性hash來解決增加或減少緩存伺服器導緻重新hash帶來的大量緩存失效的弊端
Mysql主從讀寫分離
由于資料庫的寫入壓力增加,Memcached隻能緩解資料庫的讀取壓力。讀寫集中在一個資料庫上讓資料庫不堪重負,大部分網站開始使用主從複制技術來達到讀寫分離,以提高讀寫性能和讀庫的可擴充性。Mysql的master-slave模式成為這個時候的網站标配了。
分表分庫+水準拆分+mysql叢集
在Memcached的高速緩存,MySQL的主從複制,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而資料量的持續猛增,由于MyISAM使用表鎖,在高并發下會出現嚴重的鎖問題,大量的高并發MySQL應用開始使用InnoDB引擎代替MyISAM。
同時,開始流行使用分表分庫來緩解寫壓力和資料增長的擴充問題。這個時候,分表分庫成了一個熱門技術,是面試的熱門問題也是業界讨論的熱門技術問題。也就在這個時候,MySQL推出了還不太穩定的表分區,這也給技術實力一般的公司帶來了希望。雖然MySQL推出了MySQL Cluster叢集,但性能也不能很好滿足網際網路的要求,隻是在高可靠性上提供了非常大的保證。
MySQL的擴充性瓶頸
MySQL資料庫也經常存儲一些大文本字段,導緻資料庫表非常的大,在做資料庫恢複的時候就導緻非常的慢,不容易快速恢複資料庫。比如1000萬4KB大小的文本就接近40GB的大小,如果能把這些資料從MySQL省去,MySQL将變得非常的小。關系資料庫很強大,但是它并不能很好的應付所有的應用場景。MySQL的擴充性差(需要複雜的技術來實作),大資料下IO壓力大,表結構更改困難,正是目前使用MySQL的開發人員面臨的問題。
今天是什麼樣子??
為什麼用NoSQL
為什麼使用NoSQL ?
今天我們可以通過第三方平台(如:Google,Facebook等)可以很容易的通路和抓取資料。使用者的個人資訊,社交網絡,地理位置,使用者生成的資料和使用者記錄檔已經成倍的增加。我們如果要對這些使用者資料進行挖掘,那SQL資料庫已經不适合這些應用了, NoSQL資料庫的發展也卻能很好的處理這些大的資料。
B、是什麼?
NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,泛指非關系型的資料庫。随着網際網路web2.0網站的興起,傳統的關系資料庫在應付web2.0網站,特别是超大規模和高并發的SNS類型的web2.0純動态網站已經顯得力不從心,暴露了很多難以克服的問題,而非關系型的資料庫則由于其本身的特點得到了非常迅速的發展。NoSQL資料庫的産生就是為了解決大規模資料集合多重資料種類帶來的挑戰,尤其是大資料應用難題,包括超大規模資料的存儲。
(例如谷歌或Facebook每天為他們的使用者收集萬億比特的資料)。這些類型的資料存儲不需要固定的模式,無需多餘操作就可以橫向擴充。
C、能幹嘛
易擴充
NoSQL資料庫種類繁多,但是一個共同的特點都是去掉關系資料庫的關系型特性。資料之間無關系,這樣就非常容易擴充。也無形之間,在架構的層面上帶來了可擴充的能力。
大資料量高性能
NoSQL資料庫都具有非常高的讀寫性能,尤其在大資料量下,同樣表現優秀。這得益于它的無關系性,資料庫的結構簡單。
一般MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache,在針對web2.0的互動頻繁的應用,Cache性能不高。而NoSQL的Cache是記錄級的,是一種細粒度的Cache,是以NoSQL在這個層面上來說就要性能高很多了
多樣靈活的資料模型
NoSQL無需事先為要存儲的資料建立字段,随時可以存儲自定義的資料格式。而在關系資料庫裡,增删字段是一件非常麻煩的事情。如果是非常大資料量的表,增加字段簡直就是一個噩夢。
傳統RDBMS VS NOSQL
- RDBMS
- 高度組織化結構化資料
- 結構化查詢語言(SQL)
- 資料和關系都存儲在單獨的表中。
- 資料操縱語言,資料定義語言
- 嚴格的一緻性
- 基礎事務
- NoSQL
- 代表着不僅僅是SQL
- 沒有聲明性查詢語言
-
沒有預定義的模式
-鍵 - 值對存儲,列存儲,文檔存儲,圖形資料庫
- 最終一緻性,而非ACID屬性
- 非結構化和不可預知的資料
- CAP定理
- 高性能,高可用性和可伸縮性
2)3V+3高
- 大資料時代的3V
- 海量Volume
- 多樣Variety
- 實時Velocity
- 網際網路需求的3高
- 高并發
- 高可擴
- 高性能
3)當下的NoSQL經典應用
- 當下的應用是sql和nosql一起使用
- 阿裡巴巴中文站商品資訊如何存放
架構發展曆程
演變過程
第5代
第5代架構使命
多資料源多資料類型的存儲問題
1. 商品基本資訊
- 名稱、價格,出廠日期,生産廠商等
- 關系型資料庫:mysql/oracle目前淘寶在去O化(也即拿掉Oracle),注意,淘寶内部用的Mysql是裡面的大牛自己改造過的
為什麼去IOE?
2008年,王堅加盟阿裡巴巴成為集團首席架構師,即現在的首席技術官。這位前微軟亞洲研究院常務副院長被馬雲定位為:将幫助阿裡巴巴集團建立世界級的技術團隊,并負責集團技術架構以及基礎技術平台搭建。
在加入阿裡後,帶着技術基因和學者風範的王堅就在阿裡巴巴集團提出了被稱為“去IOE”(在IT建設過程中,去除IBM小型機、Oracle資料庫及EMC儲存設備)的想法,并開始把雲計算的本質,植入阿裡IT基因。
王堅這樣概括“去IOE”運動和阿裡雲之間的關系:“去IOE”徹底改變了阿裡集團IT架構的基礎,是阿裡擁抱雲計算,産出計算服務的基礎。“去IOE”的本質是分布化,讓随處可以買到的Commodity PC架構成為可能,使雲計算能夠落地的首要條件。
2. 商品描述、詳情、評價資訊(多文字類)
- 多文字資訊描述類,IO讀寫性能變差
- 文檔資料庫MongDB中
3. 商品的圖檔
- 商品圖檔展現類
- 分布式的檔案系統中
- 淘寶自己的TFS
- Google的GFS
- Hadoop的HDFS
4. 商品的關鍵字
- 搜尋引擎,淘寶内用
- ISearch
5. 商品的波段性的熱點高頻資訊
- 記憶體資料庫
- Tair、Redis、Memcache
6. 商品的交易、價格計算、積分累計
- 外部系統,外部第3方支付接口
- 支付寶
總結大型網際網路應用(大資料、高并發、多樣資料類型)的難點和解決方案
- 難點
- 資料類型多樣性
- 資料源多樣性和變化重構
- 資料源改造而資料服務平台不需要大面積重構
-
解決辦法
阿裡、淘寶幹了什麼?UDSL
Redis簡記 什麼樣
映射
API
熱點緩存Redis簡記 Redis簡記
4)NoSQL資料模型簡介
聚合模型
-
列族
顧名思義,是按列存儲資料的。最大的特點是友善存儲結構化和半結構化資料,友善做資料壓縮,
對針對某一列或者某幾列的查詢有非常大的IO優勢。
Redis簡記 - 圖形
Redis簡記
5)NoSQL資料庫的四大分類
-
KV鍵值:典型介紹
新浪:BerkeleyDB+redis
美團:redis+tair
阿裡、百度:memcache+redis
- 文檔型資料庫(bson格式比較多):典型介紹
- CouchDB
-
MongoDB
MongoDB 是一個基于分布式檔案存儲的資料庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴充的高性能資料存儲解決方案。
MongoDB 是一個介于關系資料庫和非關系資料庫之間的産品,是非關系資料庫當中功能最豐富,最像關系資料庫的。
- 列存儲資料庫
- Cassandra, HBase
- 分布式檔案系統
- 圖關系資料庫
- 它不是放圖形的,放的是關系比如:朋友圈社交網絡、廣告推薦系統
- 社交網絡,推薦系統等。專注于建構關系圖譜
- Neo4J, InfoGrid
- 四者對比
Redis簡記
6)在分布式資料庫中CAP原理CAP+BASE
1. 傳統的ACID分别是什麼
- A (Atomicity) 原子性
- C (Consistency) 一緻性
- I (Isolation) 獨立性
- D (Durability) 持久性
2. CAP
- C:Consistency(強一緻性)
- A:Availability(可用性)
- P:Partition tolerance(分區容錯性)
3. CAP的3進2
CAP理論就是說在分布式存儲系統中,最多隻能實作上面的兩點。
而由于目前的網絡硬體肯定會出現延遲丢包等問題,是以分區容忍性是我們必須需要實作的。是以我們隻能在一緻性和可用性之間進行權衡,沒有NoSQL系統能同時保證這三點。
- CA 傳統Oracle資料庫
- AP 大多數網站架構的選擇
- CP Redis、Mongodb
注意:分布式架構的時候必須做出取舍。
一緻性和可用性之間取一個平衡。多餘大多數web應用,其實并不需要強一緻性。是以犧牲C換取P,這是目前分布式資料庫産品的方向
一緻性與可用性的決擇
對于web2.0網站來說,關系資料庫的很多主要特性卻往往無用武之地
資料庫事務一緻性需求
很多web實時系統并不要求嚴格的資料庫事務,對讀一緻性的要求很低, 有些場合對寫一緻性要求并不高。允許實作最終一緻性。
資料庫的寫實時性和讀實時性需求
對關系資料庫來說,插入一條資料之後立刻查詢,是肯定可以讀出來這條資料的,但是對于很多web應用來說,并不要求這麼高的實時性,比方說發一條消息之 後,過幾秒乃至十幾秒之後,我的訂閱者才看到這條動态是完全可以接受的。
對複雜的SQL查詢,特别是多表關聯查詢的需求
任何大資料量的web系統,都非常忌諱多個大表的關聯查詢,以及複雜的資料分析類型的報表查詢,特别是SNS類型的網站,從需求以及産品設計角 度,就避免了這種情況的産生。往往更多的隻是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。
4. 經典CAP圖
CAP理論的核心是:一個分布式系統不可能同時很好的滿足一緻性,可用性和分區容錯性這三個需求,
最多隻能同時較好的滿足兩個。
是以,根據 CAP 原理将 NoSQL 資料庫分成了滿足 CA 原則、滿足 CP 原則和滿足 AP 原則三大類:
- CA - 單點叢集,滿足一緻性,可用性的系統,通常在可擴充性上不太強大。
- CP - 滿足一緻性,分區容忍必的系統,通常性能不是特别高。
- AP - 滿足可用性,分區容忍性的系統,通常可能對一緻性要求低一些。
5. BASE
BASE就是為了解決關系資料庫強一緻性引起的問題而引起的可用性降低而提出的解決方案。
BASE其實是下面三個術語的縮寫:
- 基本可用(Basically Available)
- 軟狀态(Soft state)
- 最終一緻(Eventually consistent)
它的思想是通過讓系統放松對某一時刻資料一緻性的要求來換取系統整體伸縮性和性能上改觀。為什麼這麼說呢,緣由就在于大型系統往往由于地域分布和極高性能的要求,不可能采用分布式事務來完成這些名額,要想獲得這些名額,我們必須采用另外一種方式來完成,這裡BASE就是解決這個問題的辦法
6. 分布式+叢集簡介
分布式系統(distributed system):由多台計算機和通信的軟體元件通過計算機網絡連接配接(本地網絡或廣域網)組成。分布式系統是建立在網絡之上的軟體系統。正是因為軟體的特性,是以分布式系統具有高度的内聚性和透明性。是以,網絡和分布式系統之間的差別更多的在于高層軟體(特别是作業系統),而不是硬體。分布式系統可以應用在在不同的平台上如:Pc、工作站、區域網路和廣域網上等。
簡單來講:
- 分布式:不同的多台伺服器上面部署不同的服務子產品(工程),他們之間通過Rpc/Rmi之間通信和調用,對外提供服務群組内協作。
- 叢集:不同的多台伺服器上面部署相同的服務子產品,通過分布式排程軟體進行統一的排程,對外提供服務和通路。
2:Redis入門介紹
Redis(REmote DIctionary Server(遠端字典伺服器))是完全開源免費的,用C語言編寫的,遵守BSD協定,是一個高性能的(key/value)分布式記憶體資料庫,基于記憶體運作并支援持久化的NoSQL資料庫,是目前最熱門的NoSql資料庫之一,也被人們稱為資料結構伺服器。
Redis 與其他 key - value 緩存産品有以下三個特點
- Redis支援資料的持久化,可以将記憶體中的資料保持在磁盤中,重新開機的時候可以再次加載進行使用
- Redis不僅僅支援簡單的key-value類型的資料,同時還提供list,set,zset,hash等資料結構的存儲
- Redis支援資料的備份,即master-slave模式的資料備份
1)Redis作用
- 記憶體存儲和持久化:redis支援異步将記憶體中的資料寫到硬碟上,同時不影響繼續服務
- 取最新N個資料的操作,如:可以将最新的10條評論的ID放在Redis的List集合裡面
- 模拟類似于HttpSession這種需要設定過期時間的功能
- 釋出、訂閱消息系統
- 定時器、計數器
2)Redis安裝
Centos7中安裝redis
- 作業系統:Centos7
[root@Linux5 software]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
#核心資訊
[root@Linux5 ~]# uname -r
3.10.0-957.el7.x86_64
[root@Linux5 ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@Linux5 ~]#
- Redis版本:redis-5.0.8
下載下傳redis
[root@Linux5 software]# wget http://download.redis.io/releases/redis-5.0.8.tar.gz
--2020-04-03 02:02:02-- http://download.redis.io/releases/redis-5.0.8.tar.gz
Resolving download.redis.io (download.redis.io)... 109.74.203.151
Connecting to download.redis.io (download.redis.io)|109.74.203.151|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1985757 (1.9M) [application/x-gzip]
Saving to: ‘redis-5.0.8.tar.gz’
100%[=================================================================================================================>] 1,985,757 40.9KB/s in 45s
2020-04-03 02:02:54 (42.7 KB/s) - ‘redis-5.0.8.tar.gz’ saved [1985757/1985757]
[root@Linux5 software]#
編譯和安裝
[root@Linux5 software]# tar xzf redis-5.0.8.tar.gz
[root@Linux5 software]# ls
redis-5.0.8 redis-5.0.8.tar.gz
[root@Linux5 software]# cd redis-5.0.8
[root@Linux5 redis-5.0.8]# make
cd src && make all
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
CC Makefile.dep
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
rm -rf redis-server redis-sentinel redis-cli redis-benchmark redis-check-rdb redis-check-aof *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep dict-benchmark
(cd ../deps && make distclean)
make[2]: Entering directory `/opt/software/redis-5.0.8/deps'
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
make[2]: Leaving directory `/opt/software/redis-5.0.8/deps'
(rm -f .make-*)
echo STD=-std=c99 -pedantic -DREDIS_STATIC='' >> .make-settings
echo WARN=-Wall -W -Wno-missing-field-initializers >> .make-settings
echo OPT=-O2 >> .make-settings
echo MALLOC=jemalloc >> .make-settings
echo CFLAGS= >> .make-settings
echo LDFLAGS= >> .make-settings
echo REDIS_CFLAGS= >> .make-settings
echo REDIS_LDFLAGS= >> .make-settings
echo PREV_FINAL_CFLAGS=-std=c99 -pedantic -DREDIS_STATIC='' -Wall -W -Wno-missing-field-initializers -O2 -g -ggdb -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src -DUSE_JEMALLOC -I../deps/jemalloc/include >> .make-settings
echo PREV_FINAL_LDFLAGS= -g -ggdb -rdynamic >> .make-settings
(cd ../deps && make hiredis linenoise lua jemalloc)
make[2]: Entering directory `/opt/software/redis-5.0.8/deps'
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
(echo "" > .make-cflags)
(echo "" > .make-ldflags)
MAKE hiredis
cd hiredis && make static
make[3]: Entering directory `/opt/software/redis-5.0.8/deps/hiredis'
gcc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb net.c
make[3]: gcc: Command not found
make[3]: *** [net.o] Error 127
make[3]: Leaving directory `/opt/software/redis-5.0.8/deps/hiredis'
make[2]: *** [hiredis] Error 2
make[2]: Leaving directory `/opt/software/redis-5.0.8/deps'
make[1]: [persist-settings] Error 2 (ignored)
CC adlist.o
/bin/sh: cc: command not found
make[1]: *** [adlist.o] Error 127
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make: *** [all] Error 2
[root@Linux5 redis-5.0.8]#
"make[3]: gcc: Command not found",沒有GCC,安裝GCC
[root@Linux5 redis-5.0.8]# yum -y install gcc
再次make:
[root@Linux5 redis-5.0.8]# make
cd src && make all
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
CC Makefile.dep
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory
#include <jemalloc/jemalloc.h>
^
compilation terminated.
make[1]: *** [adlist.o] Error 1
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make: *** [all] Error 2
[root@Linux5 redis-5.0.8]#
"jemalloc/jemalloc.h: No such file or directory"
清理後,再次進行編譯:
[root@Linux5 redis-5.0.8]# make distclean
[root@Linux5 redis-5.0.8]# make
...
Hint: It's a good idea to run 'make test' ;)
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make install
[root@Linux5 redis-5.0.8]# make install
cd src && make install
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
CC Makefile.dep
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
make[1]: Entering directory `/opt/software/redis-5.0.8/src'
Hint: It's a good idea to run 'make test' ;)
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/opt/software/redis-5.0.8/src'
[root@Linux5 redis-5.0.8]#
檢視安裝路徑:
[root@Linux5 redis-5.0.8]# ll /usr/local/bin
total 32780
-rwxr-xr-x. 1 root root 4366904 Apr 3 02:15 redis-benchmark
-rwxr-xr-x. 1 root root 8125104 Apr 3 02:15 redis-check-aof
-rwxr-xr-x. 1 root root 8125104 Apr 3 02:15 redis-check-rdb
-rwxr-xr-x. 1 root root 4807888 Apr 3 02:15 redis-cli
lrwxrwxrwx. 1 root root 12 Apr 3 02:15 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 8125104 Apr 3 02:15 redis-server
-rwxr--r--. 1 root root 240 Jul 20 2019 xcall
-rwxr--r--. 1 root root 394 Jul 20 2019 xsync
[root@Linux5 redis-5.0.8]#
關于這些檔案的說明:
- Redis-benchmark:性能測試工具
- Redis-check-aof:修複有問題的AOF檔案
- Redis-check-dump:修複有問題的dump.rdb檔案
預設情況下在Redis上寫資料每秒鐘8萬,讀資料每秒鐘11萬。[root@Linux5 ~]# redis-benchmark ====== PING_INLINE ====== 100000 requests completed in 2.14 seconds 50 parallel clients 3 bytes payload keep alive: 1 85.03% <= 1 milliseconds 97.43% <= 2 milliseconds 99.29% <= 3 milliseconds 99.63% <= 4 milliseconds 99.85% <= 5 milliseconds 99.93% <= 6 milliseconds 99.95% <= 8 milliseconds 99.95% <= 9 milliseconds 99.99% <= 10 milliseconds 100.00% <= 10 milliseconds 46620.05 requests per second ====== PING_BULK ====== 100000 requests completed in 2.23 seconds 50 parallel clients 3 bytes payload keep alive: 1 84.86% <= 1 milliseconds 96.22% <= 2 milliseconds 98.92% <= 3 milliseconds 99.53% <= 4 milliseconds 99.76% <= 5 milliseconds 99.90% <= 6 milliseconds 99.93% <= 7 milliseconds 99.95% <= 8 milliseconds 99.99% <= 9 milliseconds 100.00% <= 9 milliseconds 44843.05 requests per second ====== SET ====== 100000 requests completed in 2.18 seconds 50 parallel clients 3 bytes payload keep alive: 1 83.27% <= 1 milliseconds 97.92% <= 2 milliseconds 99.62% <= 3 milliseconds 99.79% <= 4 milliseconds 99.94% <= 5 milliseconds 99.98% <= 6 milliseconds 99.98% <= 7 milliseconds 99.99% <= 9 milliseconds 99.99% <= 10 milliseconds 100.00% <= 11 milliseconds 100.00% <= 12 milliseconds 100.00% <= 14 milliseconds 100.00% <= 14 milliseconds 45955.88 requests per second ====== GET ====== 100000 requests completed in 2.10 seconds 50 parallel clients 3 bytes payload keep alive: 1 84.44% <= 1 milliseconds 98.35% <= 2 milliseconds 99.74% <= 3 milliseconds 99.88% <= 4 milliseconds 99.95% <= 5 milliseconds 99.99% <= 6 milliseconds 100.00% <= 6 milliseconds 47619.05 requests per second ====== INCR ======
- Redis-cli:用戶端,操作入口
- Redis-sentinel:redis叢集使用
- Redis-server:Redis伺服器啟動指令
拷貝“redis.conf”到“/opt/module/redis”檔案下:
[root@Linux5 redis-5.0.8]# mkdir -p /opt/module/redis
[root@Linux5 redis-5.0.8]# ls
00-RELEASENOTES CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests
BUGS COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src utils
[root@Linux5 redis-5.0.8]# cp redis.conf /opt/module/redis/
[root@Linux5 redis-5.0.8]#
啟動redis
[root@Linux5 redis-5.0.8]# redis-server /opt/module/redis/redis.conf
11461:C 03 Apr 2020 02:21:39.374 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
11461:C 03 Apr 2020 02:21:39.374 # Redis version=5.0.8, bits=64, commit=00000000, modified=0, pid=11461, just started
11461:C 03 Apr 2020 02:21:39.374 # Configuration loaded
11461:M 03 Apr 2020 02:21:39.375 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 11461
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
11461:M 03 Apr 2020 02:21:39.377 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
11461:M 03 Apr 2020 02:21:39.377 # Server initialized
11461:M 03 Apr 2020 02:21:39.377 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
11461:M 03 Apr 2020 02:21:39.377 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
11461:M 03 Apr 2020 02:21:39.377 * Ready to accept connections
這是在界面上列印了redis的啟動資訊,可以設定讓redis程序在背景運作,修改redis.conf檔案将裡面的daemonize no 改成 yes,讓服務在背景啟動。
檢視redis程序
[root@Linux5 ~]# ps -ef|grep redis
root 11461 6704 0 02:21 pts/0 00:00:00 redis-server 127.0.0.1:6379
root 11466 11299 0 02:22 pts/1 00:00:00 grep --color=auto redis
[root@Linux5 ~]# lsof -i:6379
-bash: lsof: command not found
[root@Linux5 ~]# yum whatprovides lsof
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.ustc.edu.cn
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
lsof-4.87-6.el7.x86_64 : A utility which lists open files on a Linux/UNIX system
Repo : base
[root@Linux5 ~]# yum -y install lsof-4.87-6.el7.x86_64
[root@Linux5 ~]# lsof -i:6379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 11461 root 6u IPv4 40130 0t0 TCP localhost:6379 (LISTEN)
[root@Linux5 ~]#
連接配接redis用戶端
[root@Linux5 ~]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
127.0.0.1:6379> info
# Server
redis_version:5.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c0c3cff97fc00d2d
redis_mode:standalone
os:Linux 3.10.0-957.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:11461
run_id:2b4f257679a4677bf23beccf9a8902582154e4ff
tcp_port:6379
uptime_in_seconds:343
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:8836938
executable:/opt/software/redis-5.0.8/redis-server
config_file:/opt/module/redis/redis.conf
# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
# Memory
used_memory:854544
used_memory_human:834.52K
used_memory_rss:12734464
used_memory_rss_human:12.14M
used_memory_peak:854544
used_memory_peak_human:834.52K
used_memory_peak_perc:100.03%
...
# CPU
used_cpu_sys:0.337036
used_cpu_user:0.199066
used_cpu_sys_children:0.000000
used_cpu_user_children:0.000000
# Cluster
cluster_enabled:0
# Keyspace
127.0.0.1:6379>
redis預設是不設定密碼的:
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379>
遠端連接配接redis
這裡我們采用的是Reids Desktop Manager來遠端管理Redis。
準備工作:
vi /opt/module/redis/redis.conf
修改為如下配置:
關閉防火牆:
[root@Linux5 ~]# firewall-cmd --state
running
[root@Linux5 ~]# systemctl stop firewalld.service
[root@Linux5 ~]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@Linux5 ~]# firewall-cmd --state
not running
[root@Linux5 ~]#
連接配接方法:
連接配接成功後:
關閉redis
- 單執行個體關閉:redis-cli shutdown
- 多執行個體關閉,指定端口關閉:redis-cli -p 6379 shutdown
也可以在redis-cli連接配接中關閉redis關閉Redis
Docker中安裝redis
安裝docker(已安裝可忽略)
[root@Linux5 ~]# yum -y install docker
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.ustc.edu.cn
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package docker.x86_64 2:1.13.1-109.gitcccb291.el7.centos will be installed
...
[root@Linux5 ~]# systemctl start docker //啟動docker
[root@Linux5 ~]# docker -v
Docker version 1.13.1, build cccb291/1.13.1
[root@Linux5 ~]# systemctl enable docker //開機啟動docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@Linux5 ~]#
pull redis
https://hub.docker.com/_/redis/?tab=tags
[root@Linux5 ~]# docker pull redis
Using default tag: latest
Trying to pull repository docker.io/library/redis ...
latest: Pulling from docker.io/library/redis
c499e6d256d6: Pull complete
bf1bc8a5a7e4: Pull complete
7564fb795604: Pull complete
ec6e86f783e4: Pull complete
1371d6223f46: Pull complete
021fd554320f: Pull complete
Digest: sha256:a732b1359e338a539c25346a50bf0a501120c41dc248d868e546b33e32bf4fe4
Status: Downloaded newer image for docker.io/redis:latest
##檢視所下載下傳的images
[root@Linux5 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/redis latest 4cdbec704e47 2 days ago 98.2 MB
[root@Linux5 ~]# docker run -d -p 6379:6379 --name myredis 4cdbec704e47
f3e65e372701b633141e06bc3e29da56a2882699c02a432615fe1a722539355b
[root@Linux5 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e65e372701 4cdbec704e47 "docker-entrypoint..." 21 seconds ago Up 21 seconds 0.0.0.0:6379->6379/tcp myredis
[root@Linux5 ~]#
“docker run -d -p 6379:6379 --name myredis 4cdbec704e47”的解釋。docker run運作鏡像,-d表示在背景運作,-p 6379:6379 表示将作業系統的6379端口和docker中的6379端口做映射,-name表示容器名 ,“4cdbec704e47”也即鏡像的id,也可以寫“docker.io/redis”。
使用Reids Desktop Manager來遠端管理Redis。
#擷取redis的容器ID
[root@Linux5 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e65e372701 4cdbec704e47 "docker-entrypoint..." 14 minutes ago Up 14 minutes 0.0.0.0:6379->6379/tcp myredis
#進入redis容器
[root@Linux5 ~]# docker exec -it f3e65e372701 /bin/bash
root@f3e65e372701:/data#
root@f3e65e372701:/data# ls /usr/local/bin
docker-entrypoint.sh gosu redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server
root@f3e65e372701:/data#
[root@Linux5 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e65e372701 4cdbec704e47 "docker-entrypoint..." 30 minutes ago Up 30 minutes 0.0.0.0:6379->6379/tcp myredis
#停止redis容器
[root@Linux5 ~]# docker kill f3e65e372701
f3e65e372701
[root@Linux5 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@Linux5 ~]#
3)雜項
- 單程序
- 單程序模型來處理用戶端的請求。對讀寫等事件的響應 是通過對epoll函數的包裝來做到的。Redis的實際處理速度完全依靠主程序的執行效率
- Epoll是Linux核心為處理大批量檔案描述符而作了改進的epoll,是Linux下多路複用IO接口select/poll的增強版本, 它能顯著提高程式在大量并發連接配接中隻有少量活躍的情況下的系統CPU使用率。
-
預設16個資料庫,類似數組下表從零開始,初始預設使用零号庫
設定資料庫的數量,預設資料庫為0,可以使用SELECT <dbid>指令在連接配接上指定資料庫id,
可以修改配置檔案中可以配置預設庫的數量:
# Set the number of databases. The default database is DB 0, you can select
設定資料庫的數量。預設資料庫起始于0,在每個連接配接上,使用select <dbid> 可以切換到另外的資料庫上,<dbid>的範圍為0-(databases-1)
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16
關于預設16個資料庫,實際上我們在前面通過“Reids Desktop Manager”連接配接redis的時候,已經看到了這點:
- Select指令切換資料庫
- Dbsize檢視目前資料庫的key的數量
- Flushdb:清空目前庫
- Flushall;通殺全部庫
- 統一密碼管理,16個庫都是同樣密碼,要麼都OK要麼一個也連接配接不上
- Redis索引都是從零開始
- 預設端口是6379,也即九宮格輸入的“Alessia Merz”
通過DBSIZE能夠檢視key的數量,而keys * 能夠檢視都有哪些key
?比對:
如果在某個庫下,執行FLUSHDB,則會清空目前庫。如下面是在0号庫下執行該指令後的結果:
如果想要删除整個庫,可以執行FLUSHALL。
3:Redis資料類型
1)Redis的五大資料類型
String(字元串)
- string是redis最基本的類型,可以了解成與Memcached一模一樣的類型,一個key對應一個value。
- string類型是二進制安全的。意思是redis的string可以包含任何資料。比如jpg圖檔或者序列化的對象 。
- string類型是Redis最基本的資料類型,一個redis中字元串value最多可以是512M
Hash(哈希,類似java裡的Map)
- Redis hash 是一個鍵值對集合。
- Redis hash是一個string類型的field和value的映射表,hash特别适合用于存儲對象。
- 類似Java裡面的Map<String,Object>
List(清單)
- Redis 清單是簡單的字元串清單,按照插入順序排序。可以添加一個元素導清單的頭部(左邊)或者尾部(右邊)。
- 它的底層實際是個雙向連結清單
Set(集合)
Redis的Set是string類型的無序集合。它是通過HashTable實作實作的,
Zset(sorted set:有序集合)
- Redis zset 和 set 一樣也是string類型元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double類型的分數。
- redis通過分數來為集合中的成員進行從小到大的排序。
- zset的成員是唯一的,但分數(score)卻可以重複。
2)Redis 鍵(key)
- keys *
- exists key的名字,判斷某個key是否存在
-
move key db --->目前庫就沒有了,被移除了move指令,
将一個key移動到另外一個庫中:
上面的操作是将k3,移動到2号庫中。Redis簡記 - expire key 秒鐘:為給定的key設定過期時間
- ttl key 檢視還有多少秒過期,-1表示永不過期,-2表示已過期 而且一旦過期後,通過get操作就查詢不到值了,而且keys檢視時,也不會顯示key
Redis簡記 Redis簡記 -
type key 檢視你的key是什麼類型
通過type 能夠檢視key的類型
Redis簡記
3)Redis字元串(String)
在Redis中,String是單值單value類型的。
常用方法
set/get/del/append/strlen
Incr/decr/incrby/decrby,一定要是數字才能進行加減
getrange/setrange
-
getrange:擷取指定區間範圍内的值,類似between......and的關系
從零到負一表示全部
- setrange設定指定區間範圍内的值,格式是setrange key 具體值
setex(set with expire)鍵秒值/setnx(set if not exist)
setex:設定帶過期時間的key,動态設定。
setex 鍵 秒值 真實值
setnx:隻有在 key 不存在時設定 key 的值。
mset/mget/msetnx
- mset:同時設定一個或多個 key-value 對。
- mget:擷取所有(一個或多個)給定 key 的值。
- msetnx:同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在。
Redis簡記
getset(先get再set)
getset:将給定 key 的值設為 value ,并傳回 key 的舊值(old value)。
簡單一句話,先get然後立即set
4)Redis清單(List)
在Redis中List,是單值多value類型的。
常用API
lpush/rpush/lrange
lpop/rpop
lindex,按照索引下标獲得元素(從上到下)
通過索引擷取清單中的元素 lindex key index
llen
lrem key 删N個value
- 從left往right删除2個值等于v1的元素,傳回的值為實際删除的數量
- LREM list3 0 值,表示删除全部給定的值。零個就是全部值
ltrim key 開始index 結束index,截取指定範圍的值後再指派給key
ltrim:截取指定索引區間的元素,格式是ltrim list的key 起始索引 結束索引
rpoplpush 源清單 目的清單
移除清單的最後一個元素,并将該元素添加到另一個清單并傳回
lset key index value
linsert key before/after 值1 值2
在list某個已有值的前後再添加具體值
性能總結
- 它是一個字元串連結清單,left、right都可以插入添加;
- 如果鍵不存在,建立新的連結清單;
- 如果鍵已存在,新增内容;
- 如果值全移除,對應的鍵也就消失了。
- 連結清單的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了。
5)Redis集合(Set)
6)Redis哈希(Hash)
7)Redis有序集合Zset(sorted set)
在設定資料的時候,如果有重複的key,則值會發生覆寫
setex(set with expire)鍵值秒/setnx(set if not exist)
在上面的這個操作中,如果k1b不存在,則設定值為v11,如果存在則不設定值。上面在執行setnx時,得到了響應碼0,表示失敗,在redis中響應碼0表示失敗,1表示成功,如果操作有錯誤,則給出error
通過msetnx設定值時,如果部分key已經存在,則都不生效,隻有key都不存在時,設定才生效。
LRANGE
傳回存儲在 key 的清單裡指定範圍内的元素。 start 和 end 偏移量都是基于0的下标,即list的第一個元素下标是0(list的表頭),第二個元素下标是1,以此類推。
偏移量也可以是負數,表示偏移量是從list尾部開始計數。 例如, -1 表示清單的最後一個元素,-2 是倒數第二個,以此類推。
-
求範圍函數的一緻性
如果你有一個list,裡面的元素是從0到100,那麼
這個指令會傳回11個元素,即最右邊的那個元素也會被包含在内。LRANGE list 0 10
-
超過範圍的下标
當下标超過list範圍的時候不會産生error。 如果start比list的尾部下标大的時候,會傳回一個空清單。 如果stop比list的實際尾部大的時候,Redis會當它是最後一個元素的下标。
-
傳回值
array-reply: 指定範圍裡的清單元素。
注意:LRANGE不會出隊元素,隻是檢視元素。lpop和rpop會出隊元素。
在Redis中,list使用使用是雙向連結清單來實作的,它可以作為隊列,也可以作為棧,當組合lpush+rpop或rpush+lpop時為隊列,當組合為lpush+lpop或rpush+rpop。
當組合為lpush+rpush+lpop時,前半部分為棧,後半部分為隊列:
127.0.0.1:6379> lpush mylist 0 1 2 3 4 5
(integer) 6
127.0.0.1:6379> lrange mylist 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
6) "0"
127.0.0.1:6379> rpush mylist 6 7 8 9 10
(integer) 11
127.0.0.1:6379> lrange mylist 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
6) "0"
7) "6"
8) "7"
9) "8"
10) "9"
11) "10"
127.0.0.1:6379>
127.0.0.1:6379> lpop mylist
"5"
127.0.0.1:6379> lpop mylist
"4"
127.0.0.1:6379> lpop mylist
"3"
127.0.0.1:6379> lpop mylist
"2"
127.0.0.1:6379> lpop mylist
"1"
127.0.0.1:6379> lpop mylist
"0"
127.0.0.1:6379> lpop mylist
"6"
127.0.0.1:6379> lpop mylist
"7"
127.0.0.1:6379> lpop mylist
"8"
127.0.0.1:6379> lpop mylist
"9"
127.0.0.1:6379> lpop mylist
"10"
127.0.0.1:6379> lpop mylist
(nil)
127.0.0.1:6379>
可以看到“lpush mylist 0 1 2 3 4 5”壓入順序,彈出順序為5,4,3,2,1,先入後出;“rpush mylist 6 7 8 9 10”的壓入順序,彈出順序為“6,7,8,9,10”,先入先出。
至于“lpush+rpush+rpop”同理。
你可能還會想到“lpush+lpop+rpop”或“rpush+lpop+rpop”的組合。在“lpush+lpop+rpop”中,将“lpush+lpop”看做棧,将“lpush+rpop”看做隊列即可。
LTRIM
LTRIM key start stop
起始版本:1.0.0
時間複雜度:O(N) where N is the number of elements to be removed by the operation.
修剪(trim)一個已存在的 list,這樣 list 就會隻包含指定範圍的指定元素。start 和 stop 都是由0開始計數的, 這裡的 0 是清單裡的第一個元素(表頭),1 是第二個元素,以此類推。
例如:
LTRIM foobar 0 2
将會對存儲在 foobar 的清單進行修剪,隻保留清單裡的前3個元素。
start 和 end 也可以用負數來表示與表尾的偏移量,比如 -1 表示清單裡的最後一個元素, -2 表示倒數第二個,等等。
超過範圍的下标并不會産生錯誤:如果 start 超過清單尾部,或者 start > end,結果會是清單變成空表(即該 key 會被移除)。 如果 end 超過清單尾部,Redis 會将其當作清單的最後一個元素。
LTRIM
的一個常見用法是和 LPUSH / RPUSH 一起使用。 例如:
- LPUSH mylist someelement
- LTRIM mylist 0 99
這一對指令會将一個新的元素 push 進清單裡,并保證該清單不會增長到超過100個元素。這個是很有用的,比如當用 Redis 來存儲日志。 需要特别注意的是,當用這種方式來使用 LTRIM 的時候,操作的複雜度是 O(1) , 因為平均情況下,每次隻有一個元素會被移除。
simple-string-reply
例子
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LTRIM mylist 1 -1
OK
redis> LRANGE mylist 0 -1
1) "two"
2) "three"
redis>
4:解析配置檔案
redis預設是沒有密碼的,可以通過如下的方式檢視是否要求密碼:
檢視Redis的啟動路徑:
這個路徑也就是在什麼路徑下執行啟動redis,則顯示的就是什麼路徑,不一定都是redis的安裝路徑。
注意:在什麼位置啟動redis,日志檔案就寫入到什麼路徑下。
這是由Redis的配置所規定的:
為Redis設定密碼:
進行密碼認證:
如果想要移除密碼:
Redis的緩存過期政策:
預設是永不過期:
5:redis.conf
6:Redis的持久化
修改Redis的配置檔案,在快照部分增加如下部分,隻要2分鐘内修改10次,就會生成dump檔案
啟動redis,添加如下的key和value
到達兩分鐘的時候,可以發現dump檔案已經生成了:
這個dump檔案,通常建議放置到其他裝置上,做容災備份。這裡為了友善,拷貝一份命名為“dump.rdb_bak”
如果此時清空Redis資料庫并且關閉Redis連接配接
執行Flush操作,會将記憶體中的資料刷寫到磁盤上,形成dump檔案。
在redis中dump檔案預設的命名規則為:
再次啟動redis的時候,發現沒有資料
分析原因:因為在執行flush操作後,将記憶體中資料刷寫到磁盤,這樣dump.rdb儲存了所有的database資訊,此時記憶體已經被清空,在shutdown操作時,又會生成一個dump.rdb檔案會覆寫原來的dump.rdb檔案,這個新生成的dump檔案沒有任何内容,是以當再次啟動redis時,讀取到的是一個空的dump檔案。這也是為什麼上面我們做了一個dump.rdb_bak檔案的原因。
為了能夠讓資料順利的恢複,需要删除原來的dump.rdb,将dump.rdb_bak重命名為dump.rdb。
這樣當再次啟動redis的時候,資料會恢複了
如果想要禁用save,在隻需要設定為“”即可
如果想要立即備份,則可以直接使用save指令。
開啟AOF
預設的追加檔案名:
實驗:
拷貝redis配置檔案為/myredis/redis_aof.conf
啟動Redis,AppendOnly檔案自動生成:
設定值,然後清空所有庫的資料:
能看到如下兩個檔案
删除這個rdb檔案
檢視aof檔案的内容:
可以看到包含了資料和它的庫資訊。但是也要注意到資料的末尾存在了一個FLUSHALL操作,這個需要我們手動來删除,否則在恢複的時候,依然無法正常恢複,因為最終還是會執行這個FLUSHALL指令。
再次啟動redis,資料恢複
AOF和DUMP可以同時存在,并且AOF優先級更高。
如果AOF順壞,可以使用如下的指令來進行修複
關于自動重寫。
所有的在開啟對應的政策後,如everySec,always或no,所有的操作和資料都會被追加到AOF檔案中,導緻檔案很大,此時就可以通過自動重寫來解決這個問題。
預設清空下redis的AOF檔案會在增加到原來的一倍并且檔案大小大于64M時,才會觸發自動重寫。
7:Redis的事務
執行個體:開啟事務并且批量執行插入資料操作
在一個事務内,如果不想要某次操作,可以DISCARD這個事務
如果某個事務在執行過程中出現了錯誤(出錯的任務并沒有被加入到隊列中,而是直接報錯),則整個事務也不會被送出:
在被加入到隊列中的任務,在執行過程中出現了錯誤,則隻有出錯的任務不會送出,但其他的資料能夠正常的插入
這裡k1所設定的是一個字元串,它不能自增,是以執行時會出錯,但是其他資料卻能夠正常的插入。
通過對比上面的兩個操作可以發現,它們兩者的根本差別在于,出錯時的任務是否在隊列中。
通過上面的兩個對比,可以發現Redis對于事務的支援是部分性的,不向傳統的Mysql或Oracle那樣絕對的強一緻性。
表鎖和行鎖
表鎖:鎖的是整張表。
行鎖:鎖的是表的某一行。
表鎖并發性比較差,但是一緻性比較的好。
悲觀鎖隻要沒有同步或鎖政策,操作就一定會出現問題。
樂觀鎖假設所有操作都是異步執行的,沒有并發問題,在發送并發問題時,就采用相應的同步措施。反映到資料庫中,為表的每個字段增加一個version字段,對于寫操作而言,會先查詢版本号是否相同,相同則更新,否則重新查詢,然後再更新。
8:Redis的釋出訂閱
9:Redis的複制(Master/Slave)
在主從複制中,Master負責資料的寫,從機負責資料的讀取,不負責資料的寫入,也就是說從機是隻讀的。
在沒有配置哨兵模式時,Master上的資料,Slaves會複制一遍;在Master down了後,Slaves之間不會進行選舉Master,在Master恢複後,會重建立立起與Slaves之間的關系(如果Master的資料被清空了,Slaves上儲存的資料會怎麼處理?)。在Slaves down了後,重新上線時會拷貝Master的資料到自己的倉庫中。
如果此時想要讓Slave成為Master,隻需要執行SLAVEOF no one即可