­

廬山真面目之十三微服務架構中如何在Docker上使用Redis快取

一、介紹

        1、開始說明
        在微伺服器架構中,有一個組件是不能少的,那就是快取組件。其實來說,快取組件,這個叫法不是完全正確,因為除了快取功能,它還能完成其他很多功能。我就不隱瞞了,今天我們要探討的就是Redis,作為RDBMS的一個有效的補充。現在的互聯網和以前的互聯網已經發生了翻天覆地的變化,這些變化的突出特徵就是「三高」。當然,這「三高」不是我們人類身體的三高,而是最新系統的三種特性,它們分別適合:高並發,高性能和高可用。這三種特徵是現在系統必須滿足的要求。為了滿足這三個要求,其實會有很多技術來支援,但是裡面有一個功能是必不可少的,那就是具有快取功能和分布特性的Redis,它可以為這三個特性增光添彩,今天我們就來看看它的真面目,讓我們對它有一個更全面、更直接的認識,深度我不敢說,因為自己也是在學習的過程中,如果以後有了新的體驗,再和大家分享吧。

        2、基礎環境

                2.1、作業系統:CentOs7(64bit)

        2.2、虛擬容器:Docker 19.03.13

        2.3、客 戶 端:SSH Secure Shell Client或者XShell

        2.4、虛擬系統:VMware Workstation Pro 14.1.3

        2.5、Redis版本:6.2.1(最新版本)
    
        3、docker 環境安裝

              3.1、直接執行命令,安裝 Docker 就好。

                    命令:#yum install docker

              3.2、升級 docker 為最新的版本。

                    如果大家不熟悉,可以查看我寫的文章《如何將Docker升級到最新版本 》【//www.cnblogs.com/PatrickLiu/default.html?page=3】

              3.3、設置 Docker 鏡像地址,防止拉取鏡像太慢。

                    3.3.1、編輯或者增加 daemon.json 文件。

                          命令:#vim /etc/docker/daemon.json
               
                    3.3.2、增加鏡像地址

                          {“registry-mirrors”: [“//5f2jam6c.mirror.aliyuncs.com”, “//hub-mirror.c.163.com”]}

                    3.3.3、重新載入配置文件。

                          命令:#systemctl daemon-reload

                    3.3.4、啟動 docker 服務。

                          命令:#systemctl enable docker

                    3.3.5、查看docker 的啟動狀態。

                          命令:#systemctl status docker

 1                 [root@localhost147 docker]# systemctl status docker
 2                 ● docker.service - Docker Application Container Engine
 3                    Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
 4                    Active: active (running) since 二 2021-02-23 12:40:05 CST; 3h 34min ago
 5                      Docs: https://docs.docker.com
 6                  Main PID: 1056 (dockerd)
 7                     Tasks: 15
 8                    Memory: 159.3M
 9                    CGroup: /system.slice/docker.service
10                        ├─1056 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
11                        └─1300 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 6379 -container-ip 172.17.0.2 -co...
12 
13                 2月 23 12:39:55 localhost147 dockerd[1056]: time="2021-02-23T12:39:55.385028171+08:00" level=info msg="ccRe...grpc
14                 2月 23 12:39:55 localhost147 dockerd[1056]: time="2021-02-23T12:39:55.385056316+08:00" level=info msg="Clie...grpc
15                 2月 23 12:39:55 localhost147 dockerd[1056]: time="2021-02-23T12:39:55.922090975+08:00" level=info msg="[gra...ay2"
16                 2月 23 12:39:57 localhost147 dockerd[1056]: time="2021-02-23T12:39:57.641265445+08:00" level=info msg="Load...rt."
17                 2月 23 12:40:01 localhost147 dockerd[1056]: time="2021-02-23T12:40:01.915460425+08:00" level=info msg="Defa...ess"
18                 2月 23 12:40:02 localhost147 dockerd[1056]: time="2021-02-23T12:40:02.048483718+08:00" level=info msg="Load...ne."
19                 2月 23 12:40:03 localhost147 dockerd[1056]: time="2021-02-23T12:40:03.328580189+08:00" level=info msg="Dock...10.3
20                 2月 23 12:40:03 localhost147 dockerd[1056]: time="2021-02-23T12:40:03.599126117+08:00" level=info msg="Daem...ion"
21                 2月 23 12:40:05 localhost147 systemd[1]: Started Docker Application Container Engine.
22                 2月 23 12:40:05 localhost147 dockerd[1056]: time="2021-02-23T12:40:05.134355536+08:00" level=info msg="API ...ock"
23                 Hint: Some lines were ellipsized, use -l to show in full.

二、Redis 基礎

        1、Redis 入門

              1.1、Redis 介紹

                    1.1.1、NoSQL
            
                         NoSQL:即Not-Only SQL(泛指非關係型資料庫),作為關係型資料庫的補充。

                          特徵:
                              可擴容、可伸縮。
                              大數據量下高性能
                              靈活的數據類型
                              高可用。

                    1.1.2、NoSQL分類

                          1.1.2.1、鍵值(Key-Value)存儲資料庫

                                該類資料庫主要會使用到一個哈希表,這個表中有一個特定的鍵和一個指針指向特定的數據。Key/value模型對於IT系統來說的優勢在於簡單、易部署。如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB。

                          1.1.2.2、列存儲資料庫
    
                                該類資料庫通常是用來應對分散式存儲的海量數據。鍵仍然存在,但是它們的特點是指向了多個列。這些列是由列家族來安排的。如:Cassandra, HBase, Riak.

                          1.1.2.3、文檔型資料庫

                                該類型的數據模型是版本化的文檔,半結構化的文檔以特定的格式存儲,比如JSON。文檔型資料庫可以看作是鍵值資料庫的升級版,允許之間嵌套鍵值,在處理網頁等複雜數據時,文檔型資料庫比傳統鍵值資料庫的查詢效率更高。如:CouchDB, MongoDb. 中國也有文檔型資料庫SequoiaDB,已經開源。

                          1.1.2.4、圖形(Graph)資料庫

                                圖形結構的資料庫同其他行列以及剛性結構的SQL資料庫不同,它是使用靈活的圖形模型,並且能夠擴展到多個伺服器上。NoSQL資料庫沒有標準的查詢語言(SQL),因此進行資料庫查詢需要制定數據模型。許多NoSQL資料庫都有REST式的數據介面或者查詢API。如:Neo4J, InfoGrid, Infinite Graph。

                    1.1.3、應用場景(解決方案-電商場景)
              
                          1.1.3.1、基本資訊(名稱,價格,廠商。。)—MySQL

                          1.1.3.2、商品附加資訊(描述、詳情、評論。。。)—MongoDB

                          1.1.3.3、圖片資訊—分散式文件系統

                          1.1.3.4、搜索資訊—ES,Lucene,solr

                          1.1.3.5、熱點資訊—(以上4中都可以成為熱點資訊)—Redis、memcache、tair

                    1.1.4、Redis 簡介

                          1.1.4.1、概念:Redis(REmote Dictionary Server)是用C語言開發的一個開源的高性能的鍵值對(Key-Value)資料庫。

                          1.1.4.2、特徵

                                1、數據間沒有必然的聯繫。

                                2、內部採用單執行緒機制進行工作。

                                3、高性能。50個並發執行100000個請求,讀的速度是:110000次/s,寫的速度是81000次/s。

                                4、多數據類型支援。

                                5、支援持久化,可以進行數據的災難恢復。

                          1.1.4.3、Redis 應用

                                1、為熱點數據加速查詢(主要場景),如熱點商品、熱點新聞、熱點資訊、推廣類的等高訪問量資訊等。

                                2、任務隊列,如秒殺,搶購,購票排隊等。

                                3、即時資訊查詢,如各類排行榜,各類網站訪問統計,公交到站資訊,在線人數資訊(聊天室,網站)、設備訊號等。

                                4、時效性資訊控制,如驗證碼控制,投票控制。

                                5、分散式數據共享,如分散式集群架構中的 Session 分離。

                                6、消息隊列。

                                7、分散式鎖。

                          1.1.4.4、Redis 命令行模式使用思考。

                                1、功能型命令。

                                      set name patrickliu
                                      get name

                                2、清楚螢幕命令。

                                      clear

                                3、幫助資訊命令。

                                      help 命令
                                      help @組名(tab)

                                4、退出命令。
                                      exit
                                      quit

              1.2、在 Docker 環境中安裝 Redis。

                    1.2.1、獲取Redis的鏡像。(我已經拉取了Redis的鏡像)

1                     [root@localhost147 ~]# docker pull redis
2                     Using default tag: latest
3                     latest: Pulling from library/redis
4                     Digest: sha256:0f97c1c9daf5b69b93390ccbe8d3e2971617ec4801fd0882c72bf7cad3a13494
5                     Status: Image is up to date for redis:latest
6                     docker.io/library/redis:latest

                    1.2.2、查看本地的鏡像。
                          命令:#docker images

1                     [root@localhost147 ~]# docker images
2                     REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
3                     redis        latest    621ceef7494a   5 weeks ago   104MB

                    1.2.3、創建本地的 Redis.conf 配置文件。                             

                      在/usr/local目錄下創建docker目錄
                      mkdir /usr/local/docker
                      cd /usr/local/docker
                
                      再在docker目錄下創建redis目錄
                      mkdir redis&&cd redis
                      創建配置文件,並將官網redis.conf文件配置複製下來進行修改
                      touch redis.conf
                      創建數據存儲目錄data
                      mkidr data        

                    1.2.4、修改配合文件的內容。

 1                     修改啟動默認配置(從上至下依次):
 2 
 3                     bind 127.0.0.1 #注釋掉這部分,這是限制redis只能本地訪問
 4 
 5                     protected-mode no #默認yes,開啟保護模式,限制為本地訪問
 6 
 7                     daemonize no#默認no,改為yes意為以守護進程方式啟動,可後台運行,除非kill進程,改為yes會使配置文件方式啟動redis失敗
 8 
 9                     databases 16 #資料庫個數(可選),我修改了這個只是查看是否生效。。
10 
11                     dir  ./ #輸入本地redis資料庫存放文件夾(可選)
12 
13                     appendonly yes #redis持久化(可選)
14 
15                     requirepass  密碼 #配置redis訪問密碼

                    1.2.5、創建並啟動 Redis 容器。

1                       命令:#docker run -p 6379:6379 --name redis -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
2 
3                            #docker run -p 6379:6379 --name redis -v /usr/local/docker/redis/redis6379.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data -d redis redis-server /etc/redis/redis.conf
4 
5                            #docker run -p 6379:6379 --name redis -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data -v /usr/local/docker/redis/log:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
6 
7                       命令:#docker run --name redis02 -p 6380:6379 -d redis redis-server
8                       命令:#docker run --name redis03 -p 6381:6379 -d redis redis-server

                    1.2.6、查看 Redis 容器
                          命令:#docker container ls -a

1                        [root@localhost147 ~]# docker container ps -a
2                        CONTAINER ID   IMAGE          COMMAND                  CREATED      STATUS          PORTS      NAMES
3                        16e827f0f530   redis:latest   "docker-entrypoint.s…"   5 days ago   Up 20 minutes   6379/tcp   nifty_pare
4                        [root@localhost147 ~]#

                          命令:docker ps查看運行的容器

1                       [root@localhost147 ~]# docker ps
2                       CONTAINER ID   IMAGE          COMMAND                  CREATED      STATUS          PORTS      NAMES
3                       16e827f0f530   redis:latest   "docker-entrypoint.s…"   5 days ago   Up 21 minutes   6379/tcp   nifty_pare

                    1.2.7、通過 redis-cli 連接測試使用 redis 服務
                          命令:docker exec -it redis(redis容器實例名稱或者ID) /bin/bash   進入docker終端,在終端中輸入:redis-cli

1                       [root@localhost147 ~]# docker exec -it redis /bin/bash
2                       root@16e827f0f530:/data# redis-cli
3                       127.0.0.1:6379>

 

                    1.2.8、安裝過程中,如果發現容器啟動失敗,使用docker logs查看容器日誌。
                          本例中docker容器名為redis,查看日誌命令為:docker logs -f -t –tail 100 redis

 1                     [root@localhost147 ~]# docker logs -f -t --tail 100 redis
 2                     2021-02-21T07:00:08.125899461Z 1:C 21 Feb 2021 07:00:08.120 # Warning: no config   file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
 3                     2021-02-21T07:00:08.125913118Z                 _._
 4                     2021-02-21T07:00:08.125923034Z            _.-``__ ''-._
 5                     2021-02-21T07:00:08.125932329Z       _.-``    `.  `_.  ''-._           Redis 6.0.10 (00000000/0) 64 bit
 6                     2021-02-21T07:00:08.125945417Z   .-`` .-```.  ```\/    _.,_ ''-._
 7                     2021-02-21T07:00:08.125995267Z  (    '      ,       .-`  | `,    )     Running in standalone mode
 8                     2021-02-21T07:00:08.126006795Z  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 9                     2021-02-21T07:00:08.126016251Z  |    `-._   `._    /     _.-'    |     PID: 1
10                     2021-02-21T07:00:08.126025129Z   `-._    `-._  `-./  _.-'    _.-'
11                     2021-02-21T07:00:08.126051128Z  |`-._`-._    `-.__.-'    _.-'_.-'|
12                     2021-02-21T07:00:08.126061728Z  |    `-._`-._        _.-'_.-'    |           http://redis.io
13                     2021-02-21T07:00:08.126090699Z   `-._    `-._`-.__.-'_.-'    _.-'
14                     2021-02-21T07:00:08.126130575Z  |`-._`-._    `-.__.-'    _.-'_.-'|
15                     2021-02-21T07:00:08.126141974Z  |    `-._`-._        _.-'_.-'    |
16                     2021-02-21T07:00:08.126151316Z   `-._    `-._`-.__.-'_.-'    _.-'
17                     2021-02-21T07:00:08.126160465Z       `-._    `-.__.-'    _.-'
18                     2021-02-21T07:00:08.126169239Z           `-._        _.-'
19                     2021-02-21T07:00:08.126178122Z               `-.__.-'
20                     2021-02-21T07:00:08.126186853Z
21                     2021-02-21T07:00:08.126195527Z 1:M 21 Feb 2021 07:00:08.123 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
22                     2021-02-21T07:00:08.126205108Z 1:M 21 Feb 2021 07:00:08.123 # Server initialized
23                     2021-02-21T07:00:08.126214945Z 1:M 21 Feb 2021 07:00:08.123 # 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.
24                     2021-02-21T07:00:08.126227855Z 1:M 21 Feb 2021 07:00:08.123 # 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 madvise > /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 (set to 'madvise' or 'never').
25                     2021-02-21T07:00:08.127024230Z 1:M 21 Feb 2021 07:00:08.126 * Loading RDB produced by version 6.0.10
26                     2021-02-21T07:00:08.127050705Z 1:M 21 Feb 2021 07:00:08.126 * RDB age 4015 seconds
27                     2021-02-21T07:00:08.127061365Z 1:M 21 Feb 2021 07:00:08.126 * RDB memory usage when created 0.77 Mb
28                     2021-02-21T07:00:08.127070425Z 1:M 21 Feb 2021 07:00:08.126 * DB loaded from disk: 0.002 seconds
29                     2021-02-21T07:00:08.127079397Z 1:M 21 Feb 2021 07:00:08.126 * Ready to accept connections

                    1.2.9、系統啟動,Docker 容器自動啟動,Redis 容器自動啟動。

1                      [root@localhost147 etc]# docker update redis --restart=always
2                      redis

        2、數據類型

              2.1、數據存儲類型介紹
            作為快取的組件有兩個,我個人接觸的比較多的就是Memcache和Redis,其實Memcache出來的要更久一些,但是到現在,使用的已經很少了,除非是以前就在使用這個技術。就算以前以前在使用Memcache,現在很多公司也選擇了Redis了,那是為什麼呢?有一個很重要的原因就是Redis擁有豐富的數據類型,接下來,我們就簡單認識一下它和5中核心類型,當然也包含另外3中擴展類型。我們繼續吧。

              2.2、string

                    基本操作:有關 string 存儲類型的基本操作。

                    2.2.1、set key value

1                        SET key value [EX seconds|PX milliseconds|KEEPTTL] [NX|XX]
2                         summary: Set the string value of a key
3                         since: 1.0.0
4                         group: string
5 
6 
7                       127.0.0.1:6379> set name patrickliu
8                        OK

                    2.2.2、get key

1                       GET key
2                         summary: Get the value of a key
3                         since: 1.0.0
4                         group: string
5 
6 
7                       127.0.0.1:6379> get name
8                        "patrickliu"

                    2.2.3、del key

1                       DEL key [key ...]
2                         summary: Delete a key
3                         since: 1.0.0
4                         group: generic
5 
6 
7                       127.0.0.1:6379> del name
8                         (integer) 11、表示刪除成功)

                    2.2.4、mset key1 value1 key2 value2 …

1                       MSET key value [key value ...]
2                         summary: Set multiple keys to multiple values
3                         since: 1.0.1
4                         group: string
5 
6                       127.0.0.1:6379> mset name liulei age 33 sex mail
7                        OK

                    2.2.5、mget key1 key2 …

 1                       MGET key [key ...]
 2                         summary: Get the values of all the given keys
 3                         since: 1.0.0
 4                         group: string
 5 
 6 
 7                       127.0.0.1:6379> mget name age sex
 8                       1) "patrickliu"
 9                       2) "33"
10                       3) "mail"

                    2.2.6、strlen key

1                       STRLEN key
2                         summary: Get the length of the value stored in a key
3                         since: 2.2.0
4                         group: string
5 
6 
7                       127.0.0.1:6379> strlen name
8                         (integer) 66、表示name值的長度)

                    2.2.7、append key value

 1                       APPEND key value
 2                         summary: Append a value to a key
 3                         since: 2.0.0
 4                         group: string
 5 
 6 
 7                       【存在則追加】
 8                       127.0.0.1:6379> append name king
 9                       (integer) 10
10                       127.0.0.1:6379> get name
11                       "liuleiking"
12 
13 
14                       【沒有則新建】
15                       127.0.0.1:6379> append xiong huangfeihong
16                       (integer) 12
17                       127.0.0.1:6379> get xiong
18                       "huangfeihong"

                擴展操作:

                  Tips 1:Redis 用於控制資料庫表主鍵的 ID 值,為資料庫表主鍵提供生成策略,保證資料庫表的主鍵唯一性。此方案適用於所有資料庫,且支援資料庫集群。

                    2.2.8、incr key

 1                       INCR key
 2                         summary: Increment the integer value of a key by one
 3                         since: 1.0.0
 4                         group: string
 5 
 6                       127.0.0.1:6379> get age
 7                       "33"
 8                       127.0.0.1:6379> incr age
 9                       (integer) 34
10                       127.0.0.1:6379> incr age
11                       (integer) 35

                    2.2.9、incrby key increment

 1                       INCRBY key increment
 2                         summary: Increment the integer value of a key by the given amount
 3                         since: 1.0.0
 4                         group: string
 5 
 6                       【正數是加,負數是減,只能是整數】
 7                       127.0.0.1:6379> get age
 8                       "35"
 9                       127.0.0.1:6379> incrby age 5
10                       (integer) 40
11                       127.0.0.1:6379> incrby age 6
12                       (integer) 46
13                       127.0.0.1:6379> incrby age -6
14                       (integer) 40

                    2.2.10、incrbyfloat key increment

 1                       INCRBYFLOAT key increment
 2                         summary: Increment the float value of a key by the given amount
 3                         since: 2.6.0
 4                         group: string
 5                
 6                       【正浮點數是加,負浮點數是減,只能是浮點數】
 7                       127.0.0.1:6379> set price 59
 8                       OK
 9                       127.0.0.1:6379> incrbyfloat price 5.34
10                       "64.34"
11                       127.0.0.1:6379> incrbyfloat price 0.43
12                       "64.77"
13                       127.0.0.1:6379> incrbyfloat price -0.43
14                       "64.34"

                    2.2.11、decr key

 1                       DECR key
 2                         summary: Decrement the integer value of a key by one
 3                         since: 1.0.0
 4                         group: string
 5                
 6                       127.0.0.1:6379> get age
 7                       "40"
 8                       127.0.0.1:6379> decr age
 9                       (integer) 39
10                       127.0.0.1:6379> decr age
11                       (integer) 38
12                       127.0.0.1:6379> decr age
13                       (integer) 37

                    2.2.12、decrby key increment

 1                       DECRBY key decrement
 2                         summary: Decrement the integer value of a key by the given number
 3                         since: 1.0.0
 4                         group: string
 5 
 6                       【正數是減,負數是加】
 7                       127.0.0.1:6379> get age
 8                       "37"
 9                       127.0.0.1:6379> decrby age 5
10                       (integer) 32
11                       127.0.0.1:6379> decrby age 5
12                       (integer) 27
13                       127.0.0.1:6379> decrby age 5
14                       (integer) 22
15                       127.0.0.1:6379> decrby age -5
16                       (integer) 27
17                       127.0.0.1:6379> decrby age -5
18                       (integer) 32

                          Tips 2:Redis 控制數據的生命周期,通過數據是否失效控制業務行為,適用於所有具有時效性限定控制的操作。
                             如:多久投一次票等。

                    2.2.13、setex key seconds value

 1                       SETEX key seconds value
 2                         summary: Set the value and expiration of a key
 3                         since: 2.0.0
 4                         group: string
 5 
 6                       127.0.0.1:6379> setex dog 6 tutu
 7                       OK
 8                       127.0.0.1:6379> get dog
 9                       "tutu"
10                       127.0.0.1:6379> get dog
11                       (nil)
12 
13                       【ttl key,查詢指定key剩餘秒數】
14                       127.0.0.1:6379> setex dog 6 tutu
15                       OK
16                       127.0.0.1:6379> ttl dog
17                       (integer) 3
18                       127.0.0.1:6379> ttl dog
19                       (integer) 1
20                       127.0.0.1:6379> ttl dog
21                       (integer) 0
22                       127.0.0.1:6379> ttl dog
23                       (integer) -2

                    2.2.14、psetex key milliseconds value

 1                       PSETEX key milliseconds value
 2                         summary: Set the value and expiration in milliseconds of a key
 3                         since: 2.6.0
 4                         group: string
 5 
 6                       127.0.0.1:6379> psetex dog 10000 tutu
 7                       OK
 8                       127.0.0.1:6379> get dog
 9                       "tutu"
10                       127.0.0.1:6379> get dog
11                       "tutu"
12                       127.0.0.1:6379> get dog
13                       "tutu"
14                       127.0.0.1:6379> get dog
15                       "tutu"
16                       127.0.0.1:6379> get dog
17                       "tutu"
18                       127.0.0.1:6379> get dog
19                       (nil)
20 
21                       127.0.0.1:6379> psetex dog 10000 tutu
22                       OK
23                       127.0.0.1:6379> pttl dog
24                       (integer) 5108
25                       127.0.0.1:6379> pttl dog
26                       (integer) 1722
27                       127.0.0.1:6379> pttl dog
28                       (integer) -2

                    注意事項:

                          數據操作不成功的回饋與數據正常操作之間的差異。

                          1、表示運行結果是否成功。
                              (integer)0—->false 失敗。
                              (integer)1—->true 成功。

                          2、表示運行結果值。
                              (integer)3—->3 個。
                              (integer)1—->1 個。
                
                          3、數據未獲取到
                              (nil)等同於null
                
                          4、數據量最大存儲量
                               512MB

                          5、數值結算最大範圍(java 中long 的最大值)
                               9223372036854775807

                    string 類型的應用場景:

                          1、在 Redis 中為大V用戶設定用戶資訊,以用戶主鍵和屬性值作為 key,後台設定定時刷新策略即可。
                                eg:   user(表名):ID(主鍵):605904930(主鍵值):fans(欄位)   —— 3292349。
                                eg:   user(表名):ID(主鍵):605904930(主鍵值):blogs(欄位)   —— 654。
                                eg:   user(表名):ID(主鍵):605904930(主鍵值):focuss(欄位)   —— 46。

                          2、在 Redis 中以json 格式存儲大 V 的用戶資訊,定時刷新(可以使用 hash 類型)
                                eg: user:id:594030334—->{id:594030334,name:liulei,fans:44454,blogs:435,focuss:83}
               
                          3、Redis 應用於各種結構性和非結構性高人讀數據訪問加速。

                          4、在 Redis 中 key 的設置約定。
                                表名:主鍵名:主鍵值:欄位名
                                user:   id  : 22132 :  name
                                order:  id  : 59454 : titles

              2.3、hash

                    2.3.1、string 類型的存儲的問題,存儲為json格式,方便取,但是如果要想修改其中的某個欄位,就很難了,這個時候,如果我們使用 Redis 裡面的 hash 類型,存和改都很方便了。

                            hash 類型:適合存儲對象類型的資訊。

                            hash 類型,底層使用的就是哈希表結構實現的數據存儲。

                            hash 存儲結構的優化:

                                  如果 field 數量較少,存儲結構優化為類數組結構。

                                  如果 field 數量較多,存儲結構使用 hashMap 結構。

                    基本操作
                
                    2.3.2、hset key field value

1                       HSET key field value [field value ...]
2                         summary: Set the string value of a hash field
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hset user name liulei age 38 sex mail
7                       (integer) 3

                    2.3.3、hget key field

1                       HGET key field
2                         summary: Get the value of a hash field
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hget user name
7                       "liulei"

                    2.3.4、hgetall key

 1                       HGETALL key
 2                         summary: Get all the fields and values in a hash
 3                         since: 2.0.0
 4                         group: hash
 5 
 6                       127.0.0.1:6379> hgetall user
 7                       1) "name"
 8                       2) "liulei"
 9                       3) "age"
10                       4) "38"
11                       5) "sex"
12                       6) "mail"

                    2.3.5、hdel key field [field..]

1                       HDEL key field [field ...]
2                         summary: Delete one or more hash fields
3                         since: 2.0.0
4                         group: hash
5 
6                 
7                       127.0.0.1:6379> hdel user age sex
8                       (integer) 2

                    2.3.6、hmset key field value [field value …]

 1                       HMSET key field value [field value ...]
 2                         summary: Set multiple hash fields to multiple values
 3                         since: 2.0.0
 4                         group: hash
 5              
 6                      127.0.0.1:6379> hmset user name liulei age 33 sex male
 7                       OK
 8                       127.0.0.1:6379> hgetall user
 9                       1) "name"
10                       2) "liulei"
11                       3) "age"
12                       4) "33"
13                       5) "sex"
14                       6) "male"

                    2.3.7、hmget key field [field …]

1                       HMGET key field [field ...]
2                         summary: Get the values of all the given hash fields
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hmget user name age sex
7                       1) "liulei"
8                       2) "33"
9                       3) "male"

                    2.3.8、hlen key

1                       HLEN key
2                         summary: Get the number of fields in a hash
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hlen user
7                       (integer) 3

                    2.3.9、hexists key field

1                       HEXISTS key field
2                         summary: Determine if a hash field exists
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hexists user age
7                       (integer) 1
8                       127.0.0.1:6379> hexists user height
9                       (integer) 0

               
                    2.3.10、hsetnx key field value

 1                       HSETNX key field value
 2                         summary: Set the value of a hash field, only if the field does not exist
 3                         since: 2.0.0
 4                         group: hash
 5 
 6                       127.0.0.1:6379> hsetnx user age 55
 7                       (integer) 0
 8                       127.0.0.1:6379> hgetall user
 9                       1) "name"
10                       2) "liulei"
11                       3) "age"
12                       4) "33"---【該值沒有修改,因為已經存在】
13                       5) "sex"
14                       6) "male"

                    擴展操作:

                    2.3.11、hkeys key

1                       HKEYS key
2                         summary: Get all the fields in a hash
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hkeys user
7                       1) "name"
8                       2) "age"
9                       3) "sex"

                    2.3.12、hvals key

1                       HVALS key
2                         summary: Get all the values in a hash
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hvals user
7                       1) "liulei"
8                       2) "33"
9                       3) "male"

                    2.3.13、hincrby key field increment

1                       HINCRBY key field increment
2                         summary: Increment the integer value of a hash field by the given number
3                         since: 2.0.0
4                         group: hash
5 
6                       127.0.0.1:6379> hincrby user age 5
7                       (integer) 38
8                       127.0.0.1:6379> hincrby user age -5
9                       (integer) 33

                    2.3.14、hincrbyfloat key field increment

1                       HINCRBYFLOAT key field increment
2                         summary: Increment the float value of a hash field by the given amount
3                         since: 2.6.0
4                         group: hash
5                
6                       127.0.0.1:6379> hincrbyfloat user age 4.6
7                       "37.6"
8                       127.0.0.1:6379> hincrbyfloat user age -4.6
9                       "33"

                    注意事項:

                      2.3.15、hash 類型下的 value 只能存儲字元串,不允許存儲其他數據類型,不存在嵌套現象,如果數據未找到,對應的值為(nil)。

                      2.3.16、每個 hash 可以存儲2^32-1個鍵值對。

                      2.3.17、hash 類型十分貼近對象的存儲形式,並且可以靈活的添加和刪除對象屬性,但是 hash 設計初衷不是為了存儲大量對象而設計的,切記不可濫用,更不可以將 hash 作為對象列表使用。

                      2.3.18、hgetall 操作可以獲取全部屬性,如果內部 field 過多,遍歷整體數據效率就會很低,有可能成為數據訪問瓶頸。

                    應用場景:

                      2.3.19、電商網站購物車設計與實現。
                
                      Tips 4: Redis 應用於購物車數據存儲設計。

                      Tips 5:Redis 應用於搶購、限購、限量發放優惠券、激活碼等業務的數據存儲設計。

                      string 存對象還是 hash 存對象,如果數據需要變動,修改,這樣操作頻繁,就是用hash,如果數據不變動,只是用於展示,使用string 存對象,json 格式。

            2.4、list

                    2.4.1、list 類型:

                          數據存儲需求:存儲多個數據,並對數據進入存儲空間的順序進行區分。

                          需要存儲結構:一個存儲空間保存多個數據,且通過數據可以體現進入順序。

                          List 類型:保存多個數據,底層使用雙向鏈表存儲結構實現。

                    基本操作:

                    2.4.2、lpush key value1,value2…

1                       LPUSH key element [element ...]
2                         summary: Prepend one or multiple elements to a list
3                         since: 1.0.0
4                         group: list
5 
6                       127.0.0.1:6379> lpush user a b c
7                       (integer) 3

                    2.4.3、rpush key value1,value2…

1                       RPUSH key element [element ...]
2                         summary: Append one or multiple elements to a list
3                         since: 1.0.0
4                         group: list
5 
6                       127.0.0.1:6379> lpush user a b c
7                       (integer) 3
8                       127.0.0.1:6379> rpush user e f g
9                       (integer) 6

                    2.4.4、lrange key start stop

 1                       LRANGE key start stop
 2                         summary: Get a range of elements from a list
 3                         since: 1.0.0
 4                         group: list
 5 
 6                       127.0.0.1:6379> lrange user 0 -1
 7                       1) "c"
 8                       2) "b"
 9                       3) "a"
10                       4) "e"
11                       5) "f"
12                       6) "g"

                    2.4.5、lindex key index

1                       LINDEX key index
2                         summary: Get an element from a list by its index
3                         since: 1.0.0
4                         group: list
5 
6                       127.0.0.1:6379> lindex user 4
7                       "f"

                    2.4.6、llen key

1                       LLEN key
2                         summary: Get the length of a list
3                         since: 1.0.0
4                         group: list
5 
6                       127.0.0.1:6379> llen user
7                       (integer) 6

                    2.4.7、lpop key

1                       LPOP key
2                         summary: Remove and get the first element in a list
3                         since: 1.0.0
4                         group: list
5 
6                       127.0.0.1:6379> lpop user
7                       "c"
8                       127.0.0.1:6379> lpop user
9                       "b"

                    2.4.8、rpop key

1                       RPOP key
2                         summary: Remove and get the last element in a list
3                         since: 1.0.0
4                         group: list
5     
6                       127.0.0.1:6379> rpop user
7                       "g"
8                       127.0.0.1:6379> rpop user
9                       "f"

                    擴展操作:任務隊列實現基礎

                    2.4.9、blpop key1 [key2 …] timeout b=block

 1                       BLPOP key [key ...] timeout
 2                         summary: Remove and get the first element in a list, or block until one is available
 3                         since: 2.0.0
 4                         group: list
 5 
 6                       127.0.0.1:6379> blpop user 5
 7                       1) "user"
 8                       2) "d"
 9                       127.0.0.1:6379> blpop user 5
10                       1) "user"
11                       2) "c"
12                       127.0.0.1:6379> blpop user 5
13                       1) "user"
14                       2) "b"
15                       127.0.0.1:6379> blpop user 5
16                       1) "user"
17                       2) "a"
18                       127.0.0.1:6379> blpop user 5
19 
20                       (nil)
21                       (5.00s)

                    2.4.10、brpop key1 [key2 …] timeout

 1                       BRPOP key [key ...] timeout
 2                         summary: Remove and get the last element in a list, or block until one is available
 3                         since: 2.0.0
 4                         group: list
 5 
 6                       127.0.0.1:6379> brpop user 5
 7                       1) "user"
 8                       2) "a"
 9                       127.0.0.1:6379> brpop user 5
10                       1) "user"
11                       2) "b"
12                       127.0.0.1:6379> brpop user 5
13                       1) "user"
14                       2) "c"
15                       127.0.0.1:6379> brpop user 5
16                       1) "user"
17                       2) "d"
18                       127.0.0.1:6379> brpop user 5
19                       【有段時間等待】
20                       (nil)
21                       (5.11s)

           
                    2.4.11、lrem key count value(可以中間操作)

 1                       LREM key count element
 2                         summary: Remove elements from a list
 3                         since: 1.0.0
 4                         group: list
 5 
 6                       127.0.0.1:6379> rpush user a b c d e f
 7                       (integer) 6
 8                       127.0.0.1:6379> lrange user 0 -1
 9                       1) "a"
10                       2) "b"
11                       3) "c"
12                       4) "d"
13                       5) "e"
14                       6) "f"
15                       127.0.0.1:6379> lrem user 1 c
16                       (integer) 1
17                       127.0.0.1:6379> lrange user 0 -1
18                       1) "a"
19                       2) "b"
20                       3) "d"
21                       4) "e"
22                       5) "f"

         
                    Tips 6:Redis 應用於具有操作先後順序的數據控制。

                    注意事項:

                      2.4.12、List中保存的數據都是 string 類型的,數據總容量是有限,最多存儲2^32-1個元素。

                      2.4.13、list 具有索引的概念,但是操作數據時候,通常以隊列的形式進行入隊出隊操作,或者以棧的形式進行入棧出棧操作。

                      2.4.14、獲取全部數據操作實數索引設置-1.

                      2.4.15、list 可以對數據進行分頁操作,通常第一頁的資訊來至於list,第二頁及更多的資訊通過資料庫的形式載入。

                    應用場景:

                      2.4.16、業務場景:twitter,新浪微博,騰訊微博中個人用戶的關注列表需要按用戶的關注順序進行展示,粉絲列表需要將最近關注的粉絲列在前面。

                      Tips 7:Redis 應用於最新消息展示
           

            2.5、set

                    2.5.1、Set 類型:

                          新的存儲需求:存儲大量的數據,在查詢方面提供更高的效率。
                          需要的存儲結構:能夠保存大量的數據,高校的內部存儲機制,便於查詢。
                          Set 類型:與 hash 存儲結構完全相同,僅存儲鍵,不存儲值(nil),並且值是不允許重複的。

                    基本操作:

                    2.5.2、sadd key member1 [member2 …]

 1                       SADD key member [member ...]
 2                         summary: Add one or more members to a set
 3                         since: 1.0.0
 4                         group: set
 5 
 6                       127.0.0.1:6379> sadd shuihu songjiang
 7                       (integer) 1
 8                       127.0.0.1:6379> sadd shuihu wusong
 9                       (integer) 1
10                       127.0.0.1:6379> sadd shuihu linchong
11                       (integer) 1
12                       127.0.0.1:6379>

                    2.5.3、smembers key

1                       SMEMBERS key
2                         summary: Get all the members in a set
3                         since: 1.0.0
4                         group: set
5 
6                       127.0.0.1:6379> smembers shuihu
7                       1) "linchong"
8                       2) "wusong"
9                       3) "songjiang"

                    2.5.4、srem key member1 [member2 …]

 1                       SREM key member [member ...]
 2                         summary: Remove one or more members from a set
 3                         since: 1.0.0
 4                         group: set
 5 
 6                       127.0.0.1:6379> srem shuihu linchong
 7                       (integer) 1
 8                       127.0.0.1:6379> smembers shuihu
 9                       1) "wusong"
10                       2) "songjiang"

               
                    2.5.6、scard key

1                       SCARD key
2                         summary: Get the number of members in a set
3                         since: 1.0.0
4                         group: set
5 
6 
7                       127.0.0.1:6379> scard shuihu
8                       (integer) 2

                    2.5.7、sismember key member

 1                       SISMEMBER key member
 2                         summary: Determine if a given value is a member of a set
 3                         since: 1.0.0
 4                         group: set
 5 
 6                 
 7                       127.0.0.1:6379> smembers shuihu
 8                       1) "wusong"
 9                       2) "songjiang"
10                       127.0.0.1:6379> sismember shuihu wusong
11                       (integer) 1

                    擴展操作:

                    2.5.8、srandmember key [count]

1                      SRANDMEMBER key [count]
2                         summary: Get one or multiple random members from a set
3                         since: 1.0.0
4                         group: set

                    2.5.9、spop key [count]

1                       SPOP key [count]
2                         summary: Remove and return one or multiple random members from a set
3                         since: 1.0.0
4                         group: set

                        Tip 8:Redis應用於隨機推薦類資訊檢索,例如:熱點歌單推薦,熱點新聞推薦,熱賣旅遊線路,應用App 推薦,大V推薦等。

                    2.5.10、求兩個集合的交集、並集和差集。

                          2.5.10.1、sinter key1 [key2]

1                           SINTER key [key ...]
2                             summary: Intersect multiple sets
3                             since: 1.0.0
4                             group: set

                          2.5.10.2、sunion key1 [key2]

1                           SUNION key [key ...]
2                             summary: Add multiple sets
3                             since: 1.0.0
4                             group: set

                          2.5.10.3、sdiff key1 [key2]

1                           SDIFF key [key ...]
2                             summary: Subtract multiple sets
3                             since: 1.0.0
4                             group: set

                    2.5.11、求兩個集合的交集、並集和差集並保存。

                          2.5.11.1、sinterstore destination key1 [key2]

1                             SINTERSTORE destination key [key ...]
2                             summary: Intersect multiple sets and store the resulting set in a key
3                             since: 1.0.0
4                             group: set        

                          2.5.11.2、sunionstore destination key1 [key2]

1                           SUNIONSTORE destination key [key ...]
2                             summary: Add multiple sets and store the resulting set in a key
3                             since: 1.0.0
4                             group: set

                          2.5.11.3、sdiffstore destination key1 [key2]

1                           SDIFFSTORE destination key [key ...]
2                             summary: Subtract multiple sets and store the resulting set in a key
3                             since: 1.0.0
4                             group: set                    

                    2.5.12、將指定數據從原實際和中移動到目標集合中。

1                       smove source destination member
2 
3                       SMOVE source destination member
4                         summary: Move a member from one set to another
5                         since: 1.0.0
6                         group: set

               
                    Tips 9:Redis應用於同類資訊的關聯搜索,二度關聯搜索,深度關聯搜索。

                          顯示共同關注(一度)
                          顯示共同好友(一度)

                          由用戶A出發,獲取到好友用戶B的好友資訊列表(一度)
                          由用戶A出發,獲取到好友用戶B的購物資訊列表(二度)
                          由用戶A出發,獲取到好友用戶B的遊戲充值列表(二度)

                    注意事項

                          1、Set 類型不允許數據重複,如果天劍的數據在 Set 中應存在,將只保留一份。
                          2、Set 雖然與Hash 的存儲結構相同,但是無法啟用 Hash 中的存儲值的空間。

                    應用場景

                          1、Redis可以應用於同類型不重複數據的合併操作。在許可權設計過程中,許可權會有重複的情況,可以使用Set去掉重複許可權。
                          2、【Tips 11】Redis 應用於同類型數據的快速去重。網站數據統計,PV:網站訪問量,刷新也算(string的計算器);UV:獨立用戶訪問量(建立Set模型,記錄不同Cookie數量);IP:獨立IP訪問量(建立Set模型,記錄不同IP數量)
                          3、【Tips 12】基於Redis可以製作黑名單和白名單功能。黑名單:過濾掉不想讓他們進來的;白名單:只保留能訪問的。

            2.6、sorted_set

                    2.6.1、Sorted_Set 類型。

                          1、新的存儲需求:數據排序有利於數據的有效展示,需要提供一種可以根據自身特徵進行排序的方式。
                          2、需要的存儲結構:新的存儲模型,可以保存大量數據,又可以對數據進行排序。
                          3、Sorted_Set 類型:基於 Set 類型存儲結構基礎上增加了排序欄位。

                    基本操作

                       2.6.2、zadd key score1 member1 [score2 member2]

 1                       ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
 2                         summary: Add one or more members to a sorted set, or update its score if it already exists
 3                         since: 1.2.0
 4                         group: sorted_set
 5   
 6                       127.0.0.1:6379> zadd user 89 zhangsan
 7                       (integer) 1
 8                       127.0.0.1:6379> zadd user 70 lisi
 9                       (integer) 1    
10                       127.0.0.1:6379> zadd user 55 wangwu
11                       (integer) 1

                       2.6.3、zrange key start stop [WITHSCORES]

 1                       ZRANGE key start stop [WITHSCORES]
 2                         summary: Return a range of members in a sorted set, by index
 3                         since: 1.2.0
 4                         group: sorted_set
 5 
 6                       127.0.0.1:6379> zrange user 0 -1 withscores
 7                       1) "wangwu"
 8                       2) "55"
 9                       3) "lisi"
10                       4) "70"
11                       5) "zhangsan"
12                       6) "89"

                         2.6.4、zrevrange key start stop [WITHSCORES]

 1                       ZREVRANGE key start stop [WITHSCORES]
 2                         summary: Return a range of members in a sorted set, by index, with scores ordered from high to low
 3                         since: 1.2.0
 4                         group: sorted_set
 5 
 6                       127.0.0.1:6379> zrevrange user 0 -1 withscores
 7                       1) "zhangsan"
 8                       2) "89"
 9                       3) "lisi"
10                       4) "70"
11                       5) "wangwu"
12                       6) "55"

                       2.6.5、zrem key member [member …]

 1                       ZREM key member [member ...]
 2                         summary: Remove one or more members from a sorted set
 3                         since: 1.2.0
 4                         group: sorted_set
 5 
 6                       127.0.0.1:6379> zrem user zhangsan
 7                       (integer) 1
 8                       127.0.0.1:6379> zrange user 0 -1
 9                       1) "wangwu"
10                       2) "lisi"

                       2.6.6、zrangebyscore key min max [WITHSCROES] [LIMIT]

1                       ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
2                         summary: Return a range of members in a sorted set, by score
3                         since: 1.0.5
4                         group: sorted_set
5 
6                       127.0.0.1:6379> zrangebyscore user 50 60 withscores
7                       1) "wangwu"
8                       2) "55"

                       2.6.7、zrevrangebyscroe key max min [WITHSCORES]

 1                     ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
 2                       summary: Return a range of members in a sorted set, by score, with scores ordered from high to low
 3                       since: 2.2.0
 4                       group: sorted_set
 5 
 6                     127.0.0.1:6379> zrevrangebyscore user 90 50 withscores
 7                     1) "lisi"
 8                     2) "70"
 9                     3) "wangwu"
10                     4) "55"

                       2.6.8、zremrangebyrank key start stop

 1                       ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
 2                         summary: Return a range of members in a sorted set, by score, with scores ordered from high to low
 3                         since: 2.2.0
 4                         group: sorted_set
 5 
 6                       127.0.0.1:6379> zrevrangebyscore user 90 50 withscores
 7                       1) "lisi"
 8                       2) "70"
 9                       3) "wangwu"
10                       4) "55"

                        2.6.9、zremrangebyscore key min max

1                     ZREMRANGEBYSCORE key min max
2                       summary: Remove all members in a sorted set within the given scores
3                       since: 1.2.0
4                       group: sorted_set
5                    
6                     127.0.0.1:6379> zremrangebyscore user 80 90
7                     (integer) 1

                       2.6.10、注意:
                            。min與max用於限定搜索查詢的條件。
                            。start與stop用於限定查詢範圍,作用於索引,表示開始和結束索引。
                            。offset與count用於限定查詢範圍,作用於查詢結果,表示開始位置和數據總量。

                       2.6.11、zcard key

1                       ZCARD key
2                         summary: Get the number of members in a sorted set
3                         since: 1.2.0
4                         group: sorted_set
5 
6                       127.0.0.1:6379> zcard user
7                       (integer) 3

                       2.6.12、zcount key min max

1                       ZCOUNT key min max
2                         summary: Count the members in a sorted set with scores within the given values
3                         since: 2.0.0
4                         group: sorted_set
5                      
6                       127.0.0.1:6379> zcount user 50 90
7                       (integer) 2

                       2.6.13、zinterstore destination numkeys key [key …]                          

1                       ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
2                         summary: Intersect multiple sorted sets and store the resulting sorted set in a new key
3                         since: 2.0.0
4                         group: sorted_set     

                       2.6.14、zunionstore destination numkeys key [key …]

1                     ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
2                       summary: Add multiple sorted sets and store the resulting sorted set in a new key
3                       since: 2.0.0
4                       group: sorted_set

                    擴展操作(適合榜單排行)

                       2.6.15、zrank key member

1                       ZRANK key member
2                         summary: Determine the index of a member in a sorted set
3                         since: 2.0.0
4                         group: sorted_set
5 
6                       127.0.0.1:6379> zrank user liubei
7                       (integer) 0

                       2.6.16、zrevrank key member

1                       ZREVRANK key member
2                         summary: Determine the index of a member in a sorted set, with scores ordered from high to low
3                         since: 2.0.0
4                         group: sorted_set
5 
6                       127.0.0.1:6379> zrevrank user liubei
7                       (integer) 3

                       2.6.17、zscore key member

1                       ZSCORE key member
2                         summary: Get the score associated with the given member in a sorted set
3                         since: 1.2.0
4                         group: sorted_set
5 
6                       127.0.0.1:6379> zscore user guanyu
7                       (nil)
8                       127.0.0.1:6379> zscore user liubei
9                       "5"

                       2.6.18、zincrby key increment member.

 1                       ZINCRBY key increment member
 2                         summary: Increment the score of a member in a sorted set
 3                         since: 1.2.0
 4                         group: sorted_set
 5 
 6 
 7                       127.0.0.1:6379> zincrby user 5 liubei
 8                       "5"
 9                       127.0.0.1:6379> zrange user 0 -1 withscores
10                       1) "liubei"
11                       2) "5"
12                       3) "lisi"
13                       4) "70"
14                       5) "zhangfei"
15                       6) "76"
16                       7) "sunquan"
17                       8) "99"

                      Tips 13:Redis應用於計數器組合排序對應的排名。

                   注意事項:
                        1、score保存的數據存儲空間是64位,如果是整數,範圍是:-9007199254740992~9007199254740992
                        2、score保存的數據也可以是一個雙精度的double 值,基於雙精度浮點數的特徵,可能會丟失精度,使用時要謹慎。
                        3、sorted_set 底層存儲還是基於 set 結構的,因此數據不能重複,如果重複添加相同的數據,score 值將被反覆覆蓋,保留最後一次修改的結果。

                   應用場景:
                        1、Tips 14 Redis應用於定時任務執行順序管理或者任務過期管理。基礎服務+增值服務,觀影vip,遊戲體驗vip。
                        2、關於帶有權重的任務/消息隊列。當任務或者消息待處理,形成了任務隊列或者消息隊列時,對於高優先順序的任務要保證對其優先處理,如何實現任務權重管理。對於帶有權重的任務,優先處理權重高的任務,採用 score 記錄權重即可。
                        3、Tips 15:Redis 應用於即時任務/消息隊列執行管理

            2.7、數據類型實踐案例

                    2.7.1、Tips 16:Redis 應用於顯示按次結算的服務控制。

                        1、應用場景:人工智慧領域的語義識別和自動對話殭屍未來服務業機器人應答呼叫體系中重要的技術,百度自己研製的用戶評價語義識別服務,免費開放給企業試用,同時訓練百度自己的模型,現對試用用戶的使用行為進行限速,限制每個用戶每分鐘最多發起的10次調用。

                        2、解決方案:控制用戶的訪問次數場景:可以使用計數器,時間限制可以為數據增加過期時間,到期就清空,就可以實現。

                            setex key second value,然後遞增,incr key,每次檢查次數。

                            為了避免每次檢查次數,我們可以設置int最大值,使用次數n,用int.maxvalue-n 為初始值,每次增加,到最大值會拋出異常,通過異常來處理,不用每次判斷次數。

                    2.7.2、Tips 17:Redis 應用於基於時間順序的數據操作,而不關注具體時間。

                        1、應用場景:使用微信的過程中,當微信接收消息後,會默認將最近的接受消息置頂,當多個好友及其關注的訂閱號同時發送消息時,該排序會不停的進行交替,同時還可以將重要的會話設置為置頂,一旦用戶離線後,再次打開微信,消息該按什麼順秀顯示?

                        2、解決方案:使用 list 數據結構,具有順序,消息最後發送的,時間最近,所以最新顯示,該特性是棧特性。

       3、通用命令

            3.1、key 的基本操作

                      3.1.1、del key

1                     DEL key [key ...]
2                       summary: Delete a key
3                       since: 1.0.0
4                       group: generic
5                 
6                     127.0.0.1:6379> del name
7                     (integer) 1

                      3.1.2、exists key

1                     EXISTS key [key ...]
2                       summary: Determine if a key exists
3                       since: 1.0.0
4                       group: generic
5 
6                     127.0.0.1:6379> exists name
7                     (integer) 1

                    3.1.3、type key

1                     TYPE key
2                       summary: Determine the type stored at key
3                      since: 1.0.0
4                       group: generic
5 
6                     127.0.0.1:6379> set name liulei
7                     OK                
8                     127.0.0.1:6379> type name
9                     string                

            3.2、key的擴展操作(時效性控制)

                    3.2.1、expire key seconds

1                     EXPIRE key seconds
2                       summary: Set a key's time to live in seconds
3                       since: 1.0.0
4                       group: generic

                    3.2.2、pexpire key milliseconds

                      PEXPIRE key milliseconds
                        summary: Set a key's time to live in milliseconds
                        since: 2.6.0
                        group: generic

                    3.2.3、ttl key

1                     TTL key
2                       summary: Get the time to live for a key
3                       since: 1.0.0
4                       group: generic

                    3.2.4、pttl key

1                     PTTL key
2                       summary: Get the time to live for a key in milliseconds
3                       since: 2.6.0
4                       group: generic

                    3.2.5、persist key

1                     PERSIST key
2                       summary: Remove the expiration from a key
3                       since: 2.2.0
4                       group: generic

            3.3、key 的擴展操作(查詢模式,keys * ? []pattern)

                    3.3.1、keys *

1                     keys *
3                     keys it
5                     keys *myjob

                    3.3.2、keys ?

1                     keys ??feihong 
3                     keys bao?a
5                     keys user:?
7                     keys ????

                    3.3.3、keys []

                     key u[at]er:1

            3.4、key 的其他操作

                    3.4.1、rename key newkey

1                     RENAME key newkey
2                       summary: Rename a key
3                       since: 1.0.0
4                       group: generic

                    3.4.2、renamenx key newkey

1                   RENAMENX key newkey
2                     summary: Rename a key, only if the new key does not exist
3                     since: 1.0.0
4                     group: generic

                    3.4.3、sort

1                   SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
2                     summary: Sort the elements in a list, set or sorted set
3                     since: 1.0.0
4                     group: generic

                    3.4.4、help @generic

  1             127.0.0.1:6379> help @generic
  2 
  3               DEL key [key ...]
  4               summary: Delete a key
  5               since: 1.0.0
  6 
  7               DUMP key
  8               summary: Return a serialized version of the value stored at the specified key.
  9               since: 2.6.0
 10 
 11               EXISTS key [key ...]
 12               summary: Determine if a key exists
 13               since: 1.0.0
 14 
 15               EXPIRE key seconds
 16               summary: Set a key's time to live in seconds
 17               since: 1.0.0
 18 
 19               EXPIREAT key timestamp
 20               summary: Set the expiration for a key as a UNIX timestamp
 21               since: 1.2.0
 22 
 23               KEYS pattern
 24               summary: Find all keys matching the given pattern
 25               since: 1.0.0
 26 
 27               MIGRATE host port key| destination-db timeout [COPY] [REPLACE] [AUTH password] [AUTH2 username password] [KEYS key]
 28               summary: Atomically transfer a key from a Redis instance to another one.
 29               since: 2.6.0
 30 
 31               MOVE key db
 32               summary: Move a key to another database
 33               since: 1.0.0
 34 
 35               OBJECT subcommand [arguments [arguments ...]]
 36               summary: Inspect the internals of Redis objects
 37               since: 2.2.3
 38 
 39               PERSIST key
 40               summary: Remove the expiration from a key
 41               since: 2.2.0
 42 
 43               PEXPIRE key milliseconds
 44               summary: Set a key's time to live in milliseconds
 45               since: 2.6.0
 46 
 47               PEXPIREAT key milliseconds-timestamp
 48               summary: Set the expiration for a key as a UNIX timestamp specified in milliseconds
 49               since: 2.6.0
 50 
 51               PTTL key
 52               summary: Get the time to live for a key in milliseconds
 53               since: 2.6.0
 54 
 55               RANDOMKEY -
 56               summary: Return a random key from the keyspace
 57               since: 1.0.0
 58 
 59               RENAME key newkey
 60               summary: Rename a key
 61               since: 1.0.0
 62 
 63               RENAMENX key newkey
 64               summary: Rename a key, only if the new key does not exist
 65               since: 1.0.0
 66 
 67               RESTORE key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]
 68               summary: Create a key using the provided serialized value, previously obtained using DUMP.
 69               since: 2.6.0
 70 
 71               SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
 72               summary: Incrementally iterate the keys space
 73               since: 2.8.0
 74 
 75               SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
 76               summary: Sort the elements in a list, set or sorted set
 77               since: 1.0.0
 78 
 79               TOUCH key [key ...]
 80               summary: Alters the last access time of a key(s). Returns the number of existing keys specified.
 81               since: 3.2.1
 82 
 83               TTL key
 84               summary: Get the time to live for a key
 85               since: 1.0.0
 86 
 87               TYPE key
 88               summary: Determine the type stored at key
 89               since: 1.0.0
 90 
 91               UNLINK key [key ...]
 92               summary: Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.
 93               since: 4.0.0
 94 
 95               WAIT numreplicas timeout
 96               summary: Wait for the synchronous replication of all the write commands sent in the context of the current connection
 97               since: 3.0.0
 98 
 99               HOST: ...options...
100               summary: Help not available
101               since: not known
102 
103               XSETID key arg
104               summary: Help not available
105               since: not known
106 
107               BITFIELD_RO key ...options...
108               summary: Help not available
109               since: not known
110 
111               SUBSTR key arg arg
112               summary: Help not available
113               since: not known
114 
115               GEORADIUS_RO key arg arg arg arg ...options...
116               summary: Help not available
117               since: not known
118 
119               PFSELFTEST
120               summary: Help not available
121               since: not known
122 
123               ASKING
124               summary: Help not available
125               since: not known
126 
127               RESTORE-ASKING key arg arg ...options...
128               summary: Help not available
129               since: not known
130 
131               PFDEBUG arg arg ...options...
132               summary: Help not available
133               since: not known
134 
135               GEORADIUSBYMEMBER_RO key arg arg arg ...options...
136               summary: Help not available
137               since: not known
138 
139               POST ...options...
140               summary: Help not available
141               since: not known
142 
143               REPLCONF ...options...
144               summary: Help not available
145               since: not known

            3.5、db 的基本操作

                    3.5.1、select index

1                      SELECT index
2                       summary: Change the selected database for the current connection
3                       since: 1.0.0
4                       group: connection
5 
6                     127.0.0.1:6379> select 1
7                     OK
8                     127.0.0.1:6379[1]>

                    3.5.2、quit

1                     QUIT -
2                       summary: Close the connection
3                       since: 1.0.0
4                       group: connection

                    3.5.3、ping

1                     PING [message]
2                       summary: Ping the server
3                       since: 1.0.0
4                       group: connection
5 
6                     127.0.0.1:6379> ping
7                     PONG
8                     127.0.0.1:6379> ping huangfeihong
9                     "huangfeihong"

                    3.5.4、echo

1                     ECHO message
2                       summary: Echo the given string
3                       since: 1.0.0
4                       group: connection
5 
6                     127.0.0.1:6379> echo nihao
7                     "nihao"

            3.6、db 的相關操作

                    3.6.1、move key db

1                     MOVE key db
2                         summary: Move a key to another database
3                         since: 1.0.0
4                         group: generic

                    3.6.2、dbsize

1                     DBSIZE -
2                       summary: Return the number of keys in the selected database
3                       since: 1.0.0
4                       group: server
5   
6 
7                     127.0.0.1:6379> dbsize
8                     (integer) 0

                    3.6.3、flushdb

1                     FLUSHDB [ASYNC]
2                       summary: Remove all keys from the current database
3                       since: 1.0.0
4                       group: server
5 
6                     127.0.0.1:6379> flushdb
7                     OK

                    3.6.4、flushall

1                   FLUSHALL [ASYNC]
2                     summary: Remove all keys from all databases
3                     since: 1.0.0
4                     group: server
5 
6                   127.0.0.1:6379> flushall
7                   OK

三、Redis高級

        1、Redis安裝

              1.1、默認啟動

                    1.1.1、伺服器端:進入redis安裝目錄,直接執行 redis-server,埠默認:6379

                     1.1.2、客戶端:進入redis安裝目錄,直接執行 redis-cli,埠默認:6379

              1.2、帶參數啟動

                    1.2.1、伺服器端:進入redis安裝目錄,直接執行 redis-server –port 6379 –host ip

                     1.2.2、客戶端:進入redis安裝目錄,直接執行 redis-cli -p 6379 -h ip

              1.3、配置文件

                    1.3.1、伺服器端:進入redis安裝目錄,直接執行 redis-server redis.conf,如果想要啟動多個redis實例,可以複製多個redis.conf配置文件,指定配置文件啟動

                          命令:#redis-server redis.conf

                          命令:#redis-server redis6380.conf

                          命令:#redis-server redis6381.conf

                    1.3.2、客戶端:進入redis安裝目錄,直接執行 redis-cli -p port -h ip,如果有多少個實例,啟動客戶端要鏈接指定埠和地址的redis實例。

                          命令:#redis-cli -p 6379

                          命令:#redis-cli -p 6380

                          命令:#redis-cli -p 6381
                   
                    1.3.3、查看redis配置文件,過濾備註和空格

                          1.3.3.1、查看redis.conf文件,過濾「#」和「空格」。

                                 命令:#cat redis.conf |grep -v “#” |grep -v “^$”

                          1.3.3.2、查看redis.conf文件,過濾「#」「空格」,生成新的文件。

                                 命令:#cat redis.conf |grep -v “#” |grep -v “^$” > redis-default.conf

              1.4、查看實例

 1                 命令:#ps -ef|grep redis-
 2 
 3                   [root@localhost147 redis]# ps -ef|grep redis
 4                   polkitd    1233   1211  0 12:24 ?        00:00:12 redis-server 127.0.0.1:6379
 5                   polkitd    1561   1541  0 12:50 ?        00:00:06 redis-server *:6379
 6                   polkitd    1649   1630  0 12:50 ?        00:00:05 redis-server *:6379
 7 
 8 
 9                 命令:#docker container ls
10 
11                   [root@localhost147 redis]# docker container ls
12                   CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES
13                   5ea80b52539f   redis     "docker-entrypoint.s…"   29 minutes ago   Up 29 minutes   0.0.0.0:6381->6379/tcp   redis03
14                   a86b55a8df2f   redis     "docker-entrypoint.s…"   30 minutes ago   Up 30 minutes   0.0.0.0:6380->6379/tcp   redis02
15                   1afed023ec60   redis     "docker-entrypoint.s…"   5 days ago       Up 55 minutes   0.0.0.0:6379->6379/tcp   redis

        2、持久化

              2.1、持久化簡介

                    2.1.1、利用永久性存儲介質將數據進行保存,在特定的時間將保存的數據進行恢復的工作機制。

                     2.1.2、防止數據丟失,確保數據的安全性。

                     2.1.3、持久化方式:數據快照(RDB),操作日誌(AOF)

              2.2、持久化(RDB)
            
                    2.2.1、RDB啟動方式–save命令,手動執行一次就保存一次數據。
                          
                    2.2.2、dbfilename dump.rdb

                          說明:設置本地資料庫文件名,默認值:dump.rdb

                          經驗:通常設置為 dump-埠號.rdb

                    2.2.3、dir

                          說明:設置存儲 rdb 文件的路徑,不包含文件名。

                          經驗:通常設置成存儲空間較大的目錄中,目錄名:data

                    2.2.4、    rdbcompression yes

                          說明:設置存儲至本地資料庫時是否壓縮數據,默認值:yes,採用lzf壓縮。

                          經驗:通常默認為開啟狀態,如果設置為no,可以節省 cpu 運行時間,但會使存儲的文件變大。

                    2.2.5、    rdbchecksum yes

                          說明:設置是否進行RDB文件格式的校驗,該校驗過程在寫文件和讀文件均進行。

                          經驗:通常默認開啟狀態,若果設置為 no,可以節約讀寫過程中約10%的時間消耗,但是存儲一定數據損壞的風險。

                    2.2.6、bgsave,不是立刻執行,後台運行。

                    2.2.7、stop-writes-on-bgsave-error yes

                          說明:後台存儲過程中如果出現錯誤現象,是否停止保存操作。

                          經驗:通常默認開始狀態。

                    2.2.8、自動執行

                          save second changes:滿足限定時間範圍內key的變化數量達到指定數量就進行持久化。

                          second:監控的時間範圍。

                          changes:監控key的變化量。

                    2.2.9、RDB特殊啟動形式

                          全量複製:在主從複製中執行。

                          伺服器運行過程中重啟:debug reload

                          關閉伺服器時指定保存數據:shutdown save

                    2.2.10、RDB優缺點:

                         2.2.10.1、優點:

                              2.2.10.1.1、RDB是一個緊湊壓縮的二進位文件,存儲效率較高。

                              2.2.10.1.2、RDB內部存儲的是Redis在某個時間點的資料庫快照,非常適用於數據備份,全量複製等場景。

                              2.2.10.1.3、RDB恢複數據的速度比AOF 快很多。

                              2.2.10.1.4、伺服器中每 X 小時執行bgsave 備份,並將RDB文件拷貝到遠程伺服器中,用於災難恢復。

                        2.2.10.2、缺點

                              2.2.10.2.1、RDB方式無論是執行指令還是利用配置,無法做到實時持久化,具有較大的可能性丟失數據。

                              2.2.10.2.2、bgsave指令每次運行都要 fork 操作創建子進程,都要犧牲掉一些性能。

                              2.2.10.2.3、Redis 的眾多版本中未進行RDB文件格式的版本統一,有可能出現各個版本服務之間的數據格式無法兼容的現象。

              2.3、持久化(AOF)

                    2.3.1、RDB存儲的弊端

                          2.3.1.1、存儲的數據量較大 ,效率比較低。基於快照思想,每次都是全部數據,當數據量巨大時,效率非常低。

                          2.3.1.2、大數據量下的IO性能較低。

                          2.3.1.3、基於 fork 創建的子進程,會產生額外的記憶體消耗。

                          2.3.1.4、宕機帶來的數據丟失風險。

                    2.3.2、AOF 寫數據的過程。

                          always(每次)每次寫入操作均同步到AOF文件中,數據零誤差,性能較低,不建議使用。

                          everysec(每秒)每秒將緩衝區中的指令同步到AOF 文件中,數據準確性較高,性能較高,建議使用。也是默認配置。

                          no(系統控制)由作業系統控制每次同步到AOF文件的周期,整體過程不可控。

                    2.3.3、AOF 啟動過程。

                          appendonly yes|no  是否開啟AOF持久化功能,默認不開啟。

                          appendfsync always|everysec|no  AOF寫數據策略。

                    2.3.4、AOF相關配置

                          appendfilename filename   AOF持久化文件名,默認文件名:appendonly.aof,建議配置:appendonly-埠號.aof

                          dir  AOF持久化文件保存的路徑,與RDB持久化文件保持一致即可。

                    2.3.5、AOF重寫

                          2.3.5.1、定義:隨著命令不斷的寫入AOF文件,文件會越來越大,文件裡面可能包含一些無效的命令,或者是重複的命令,為了解決這個問題,Redis引入了AOF重寫機制來壓縮文件體積。AOF文件重寫是將Redis進程內的數據轉換為寫命令同步到新AOF文件的過程。簡單的說就是將對同一個數據的若干條命令執行結果轉化成最終結果數據對應的指令進行記錄。

                          2.3.5.2、AOF重寫作用

                                降低磁碟佔用量,提高磁碟利用率。

                                提高持久化效率,降低持久化寫時間,提高IO性能。

                                降低數據恢復用時,提高數據恢復效率。

                          2.3.5.3、重寫規則

                                進程內已經超時的數據不再寫入文件。

                                忽略無效指令,重寫時使用進程內數據直接生成,這樣新的AOF文件只保留最終數據的寫入命令。del key1,hdel key2,srem key3 set key4 1111,set key 4 222 等。

                                對同一數據的多條寫入命令合併為一條命令。如:lpush list1 a,lpush list1 b,lpush list1 c,lpush list1 d 合併為 lpush list1 a b c d。

                    2.3.6、AOF重寫方式

                          2.3.6.1、手動重寫

                                bgrewriteaof

1                           127.0.0.1:6379> bgrewriteaof
2                           Background append only file rewriting started

                          2.3.6.2、自動重寫

                                2.3.6.2.1、自動重寫觸發條件設置

1                                 auto-aof-rewrite-min-size size
2                                 自動重寫最小值
3 
4                                 auto-aof-rewrite-percentage percent
5                                 自動重寫百分比

                                2.3.6.2.2、自動重寫觸發對比參數

1                                 aof_current_size
2                                 在緩衝區中當前數據的大小
3 
4                                 aof_base_size
5                                 基礎大小

                                2.3.6.2.3、自動重寫觸發條件

                                aof_current_size>auto-aof-rewrite-min-size

                                aof_current_size - aof_base_size
                                     -------------------------------------->=auto-aof-rewrite-percentage
                                        aof_base_size

                    2.3.7、AOF工作流程

                          2.3.7.1、always:執行指令Set—>主進程—->fork子進程—->把操作資訊寫入aof(非重寫了)
                                            |
                                              ——>執行Set操作

                          2.3.7.2、everysec:執行指令Set—>主進程—>fork啟動子進程—>aof緩衝區—>把資訊寫入aof(非重寫)
                                              |
                                                ——>執行Set操作

                          2.3.7.3、everysec+rewrite:執行指令Set—>主進程—>fork啟動子進程—>aof緩衝區—–>非重寫了aof
                                                 |                 |                            |
                                                  —–>執行Set操作       ——>aof重寫緩衝區     |
                                                             |       合併替換
                                                             使用以上數據          |
                                               【Background append…started】                 |          |
                                           |            |                        |          |
                              執行bgrewriteaof—->創建主進程——>fork同時創建子進程——–>重寫新的AOF文件。—-

                    
              2.4、RDB與AOF區別

                    2.4.1、佔用存儲空間,RDB相對較小,它存的是數據,而且是壓縮的;AOF存的是指令級別的數據,相對而言較大。

                    2.4.2、存儲速度:RDB數據小的時候,挺快的,數據一大,就慢了;AOF是秒級別存儲,肯定快。

                    2.4.3、恢復速度:RDB快,直接恢複數據;AOF慢,執行指令來恢復。

                    2.4.4、數據安全性:RDB 會丟失數據;AOF依據策略決定。

                    2.4,5、資源消耗:RDB 高/重量級;AOF 低/輕量級

                    2.4.6、啟動優先順序:RDB要低,AOF高

              2.5、持久化的場景

        3、redis.conf

              3.1、設置伺服器已守護進程的方式運行。

                    daemonize yes|no

              3.2、綁定主機地址

                    bind 127.0.0.1

              3.3、設置伺服器埠號

                    port 6379

              3.4、設置資料庫數量

                    database 16

              3.5、設置日誌記錄級別,默認:notice,如果想獲取更多調試資訊:debug

                    loglevel debug|verbose|notice|warning

              3.6、設置日誌記錄文件名

                    logfile 埠號.log

              3.7、設置同一時間最大客戶端連接數,默認值:0,無限制,當客戶端連接達到上限,redis會關閉新的連接。

                    maxclients 0

              3.8、客戶端閑置等待最大時長,達到最大值後會關閉連接,如果需要關閉該功能,設置:0

                    timeout 300

              3.9、多伺服器快捷配置。導入並載入指定配置文件資訊,用於快捷創建redis公共配置較多的redis實例配置文件,便於維護。

                    include /path/server-埠號.conf

        4、事務

              4.1、redis事務就是一個命令執行的隊列,將一系列預定義命令包裝成一個整體(一個隊列),當執行時,一次性按照添加順序依次執行,中間不會被打斷或干擾。

              4.2、事務基本操作

                    4.2.1、multi 開始事務

 1                      MULTI -
 2                       summary: Mark the start of a transaction block
 3                       since: 1.2.0
 4                       group: transactions
 5 
 6                     127.0.0.1:6379> multi
 7                     OK
 8                     127.0.0.1:6379> set name liulei
 9                     QUEUED
10                     127.0.0.1:6379> get name
11                     QUEUED
12                     127.0.0.1:6379> exec
13                     1) OK
14                     2) "liulei"
15                     127.0.0.1:6379>

                    4.2.2、discard 取消事務

 1                     DISCARD -
 2                       summary: Discard all commands issued after MULTI
 3                       since: 2.0.0        
 4                       group: transactions
 5 
 6                     127.0.0.1:6379> multi
 7                     OK
 8                     127.0.0.1:6379> set age 33
 9                     QUEUED
10                     127.0.0.1:6379> get age
11                     QUEUED
12                     127.0.0.1:6379> discard
13                     OK
14                     127.0.0.1:6379> exec
15                     (error) ERR EXEC without MULTI
16                     127.0.0.1:6379>

                    4.2.3、exec 執行事務

1                     EXEC -
2                       summary: Execute all commands issued after MULTI
3                       since: 1.2.0
4                       group: transactions

              4.3、鎖

                    4.3.1、watch key1 [key2…]

 1                     WATCH key [key ...]
 2                       summary: Watch the given keys to determine execution of the MULTI/EXEC block
 3                       since: 2.2.0
 4                       group: transactions
 5                 
 6                     127.0.0.1:6379> set name liulei
 7                     OK
 8                     127.0.0.1:6379> set age 33
 9                     OK
10                     127.0.0.1:6379> watch name age
11                     OK
12                     127.0.0.1:6379> multi
13                     OK
14                     127.0.0.1:6379> incr age
15                     QUEUED
16                     127.0.0.1:6379> get name
17                     QUEUED
18                     127.0.0.1:6379> exec
19                     1) (integer) 34
20                     2) "liulei"

                    4.3.2、unwatch

1                     UNWATCH -
2                       summary: Forget about all watched keys
3                       since: 2.2.0
4                       group: transactions
5 
6                     127.0.0.1:6379> unwatch
7                     OK

                    4.3.3、Tips 18 Redis 應用於基於狀態控制的批量任務執行。

                    4.3.4、超買問題–分散式鎖

 1                     SETNX key value
 2                       summary: Set the value of a key, only if the key does not exist
 3                       since: 1.0.0
 4                       group: string
 5 
 6                     127.0.0.1:6379> setnx name liulei(加鎖)
 7                     (integer) 1
 8                     127.0.0.1:6379> setnx name zhangfei
 9                     (integer) 0
10                     127.0.0.1::6379>del name(取消鎖)
11                     ok

                    4.3.5、Tips 19 Redis 應用基於分散式鎖的對應的場景控制。

                    4.3.6、死鎖問題—->為鎖增加過期時間 expire pexpire

                          例如:持有鎖的操作最長執行時間127ms,最短執行時間7ms。

                          測試百萬次最長執行時間對應命令的最大耗時,測試百萬次網路延遲平均耗時。

                          鎖時間設定推薦:最大耗時*120%+平均網路延遲*110%

                          如果業務最大耗時<<網路平均延遲,通常為2個數量級,取其中單個耗時較長即可。

        5、刪除策略

              5.1、過期數據

                    Redis是一種記憶體資料庫,所有數據均存放在記憶體中,記憶體中的數據可以通過 TTL 指令獲取其狀態。

                        xx:具有時效性的數據

                        -1:永久有效的數據

                        -2:已經過期的數據 或者 被刪除的數據 或者 未定義的數據。

              5.2、數據刪除策略(針對過期數據)

                    5.2.1、定時刪除

                          定義:創建一個定時器,當 key 設置有過期的時間,且過期時間達到時,由定時器任務立即執行對鍵的刪除操作。

                          優點:節約記憶體,到時就刪除,快速釋放掉不必要的記憶體佔用。
                          缺點:CPU壓力很大,無論CPU此時負載量多高,均佔用CPU,會影響 redis 伺服器相應時間和指令的吞吐量。
                          總結:用處理器性能換取存儲空間。

                    5.2.2、惰性刪除

                          定義:數據達到過期時間,並不會立刻刪除,而是等到下一次再次訪問的時候,如果未過期,就返回數據,如果發現已過期,刪除,返回不存在。expireIfNeeded()

                          優點:節約CPU性能,發現必須刪除的時候才刪除。
                          缺點:記憶體壓力很大,出現長期佔用記憶體的數據。
                          總結:用存儲空間換CPU處理器的性能。

                    5.2.3、定期刪除(周期)

                          定義:上面兩種方案都很極端,定期刪除就是折中方案。Redis 啟動伺服器初始化時,讀取配置 server.hz 的值,默認為10。

                            1、每秒執行 server.hz 次 serverCron()【伺服器定時輪訓】。在該方法內部調用 databaseCron() 方法,輪訓所有資料庫,默認16個。針對每個資料庫調用 activeExpireCycle() 方法。

                            2、activeExpireCycle() 對每個 expires[*] 逐一進行檢測,每次執行 250ms / server.hz。

                            3、對某個expires[*]檢測是,隨機挑選 W 個 key 檢測。

                                  3.1、如果 key 超時,刪除key.

                                  3.2、如果一輪中刪除的 key 的數量 > W*25%,循環該過程。

                                  3.3、如果一輪中刪除的 key 的數量 <= W*25%,檢查下一個expires[*],0-15 循環

                                  3.4、W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 屬性值。

                            4、參數 current_db 用於記錄 activeExpireCycle() 進入那個 expires[*]執行。

                            5、如果 activeExpireCycle()執行時間到期,下次從 current_db 繼續向下執行。

                          優點:周期性輪詢 redis 庫中的時效性數據,採用隨機抽取的策略,利用過期數據佔比的方式控制刪除頻度。
                          特點:CPU 性能佔用設置有峰值,檢測頻度可自定義設置。
                              記憶體眼裡不是很大,長期佔用記憶體的零數據會被持續清理。
                          總結:周期性的抽查存儲空間(隨機抽查,重點抽查)

              5.3、逐出演算法(針對有效的數據,無過期限制的數據)

                    5.3.1、定義:Redis使用記憶體存儲數據,在執行每一個命令前,會調用 freeMemoryIfNeeded()方法檢測記憶體是否充足,如果記憶體不滿足新加入的數據的最低存儲要求,redis 要臨時刪除一些數據為當前指令清理存儲空間,清理數據的策略就是逐出演算法。

                    5.3.2、注意:逐出數據的過程不是100%能夠清理出足夠的可使用的記憶體空間,如果不成功則反覆執行,當對所有數據嘗試完畢後,如果不能達到記憶體清理的要求,將出現錯誤資訊。

                          (error)OOM command not allowed when used memory>’maxmemory’

                    5.3.3、最大可使用記憶體。

                          maxmemory     佔用物理記憶體的比例,默認值:0,表示不限制,生產環境根據需求設定,通常設置在50%以上,或者70%。

                    5.3.4、每次選取待刪除數據的個數。

                          maxmemory-samples        選取數據時並不會全庫掃描,導致嚴重的性能消耗,降低讀寫性能,因此採用隨機獲取數據的方式作為待檢測刪除數據。

                    5.3.5、刪除策略

                          maxmemory-policy volatile-lru       達到最大記憶體後,對被挑選出來的數據進行刪除策略。 檢查易失數據(可能會過期的數據集:server.db[i].expires)

                            5.3.5.1、volatile-lru:挑選最近最少使用的數據淘汰(Least Recently Used)【默認】

                            5.3.5.2、volatile-lfu:挑選最近使用次數最少的數據淘汰(Least Frequently Used)

                            5.3.5.3、volatile-ttl:挑選將要過期的數據淘汰。

                            5.3.5.4、volatile-random:任意選擇數據淘汰。

                          檢測全庫數據(所有數據集:server.db[i].dict)

                            5.3.5.5、allkeys-lru:挑選最近最少使用的數據淘汰(Least Recently Used)

                            5.3.5.6、allkeys-lfu:挑選最近使用次數最少的數據淘汰(Least Frequently Used)

                            5.3.5.7、allkeys-random:任意選擇數據淘汰。

                          放棄數據驅逐

                            5.3.5.8、no-enviction:禁止驅逐數據(Redis 4.0 默認策略),會引發錯誤 OOM(Out Of Memory)。

                    5.3.6、數據逐出策略配置依據

                          使用 info 命令輸出監控資訊,查詢快取 hit 和 miss 的次數,根據訛誤需求調優 redis 配置。

1                       127.0.0.1:6379> info stats
2                       # Stats    
3                       keyspace_hits:1
4                       keyspace_misses:0

        6、高級數據類型

              6.1、Bitmaps(統計狀態:性別,好壞,看與不看等等,就兩個狀態,是或者否)

                    6.1.1、getbit key offset

1                       GETBIT key offset
2                         summary: Returns the bit value at offset in the string value stored at key
3                         since: 2.2.0
4                         group: string
5 
6                       127.0.0.1:6379> getbit bits 0
7                       (integer) 1

                    6.1.2、SETBIT key offset value

1                       SETBIT key offset value
2                         summary: Sets or clears the bit at offset in the string value stored at key
3                         since: 2.2.0
4                         group: string
5 
6                       127.0.0.1:6379> setbit bits 0 1
7                       (integer) 0

                    6.1.3、bitop op destKey key1 [key2 …]對指定的 key 按位進行交、並、非、異或操作,並將結果保存到 destKey 中。

 1                       BITOP operation destkey key [key ...]
 2                         summary: Perform bitwise operations between strings
 3                         since: 2.6.0
 4                         group: string
 5 
 6                       and:交
 7 
 8                       or:並
 9 
10                       not:非
11 
12                       xor:異或
13                 
14                       127.0.0.1:6379> setbit 20880808 0 1
15                       (integer) 0
16                       127.0.0.1:6379> setbit 20880808 4 1
17                       (integer) 0
18                       127.0.0.1:6379> setbit 20880808 8 1
19                       (integer) 0
20                       127.0.0.1:6379> setbit 20880809 0 1
21                       (integer) 1
22                       127.0.0.1:6379> setbit 20880809 5 1
23                       (integer) 0
24                       127.0.0.1:6379> setbit 20880809 8 1
25                       (integer) 1
26 
27                       127.0.0.1:6379> bitop or 08-09 20880808 20880809
28                       (integer) 2
29 
30                       127.0.0.1:6379> bitcount 08-09
31                       (integer) 4

                    6.1.4、bitcount key [start end],統計指定 key 中 1 的數量。

 1                       BITCOUNT key [start end]
 2                         summary: Count set bits in a string
 3                         since: 2.6.0
 4                         group: string
 5 
 6                       127.0.0.1:6379> setbit 20880808 0 1
 7                       (integer) 0
 8                       127.0.0.1:6379> setbit 20880808 4 1
 9                       (integer) 0
10                       127.0.0.1:6379> setbit 20880808 8 1
11                       (integer) 0
12                       127.0.0.1:6379> setbit 20880809 0 1
13                       (integer) 1
14                       127.0.0.1:6379> setbit 20880809 5 1
15                       (integer) 0
16                       127.0.0.1:6379> setbit 20880809 8 1
17                       (integer) 1
18 
19                       127.0.0.1:6379> bitcount 20880809
20                       (integer) 3
21                       127.0.0.1:6379> bitcount 20880808
22                       (integer) 3

                    6.1.5、Tips 21:redis 應用於資訊狀態的統計。

              6.2、Hyperloglog(統計不重複的數據,基數統計,獨立UV)

                    6.2.1、添加數據

 1                       pfadd key element [element ...]
 2 
 3                       PFADD key element [element ...]
 4                         summary: Adds the specified elements to the specified HyperLogLog.
 5                         since: 2.8.9
 6                         group: hyperloglog
 7 
 8                       127.0.0.1:6379> pfadd hll 001
 9                       (integer) 1
10                       127.0.0.1:6379> pfadd hll 001
11                       (integer) 0
12                       127.0.0.1:6379> pfadd hll 001
13                       (integer) 0
14                       127.0.0.1:6379> pfadd hll 001
15                       (integer) 0
16                       127.0.0.1:6379> pfadd hll 001
17                       (integer) 0
18                       127.0.0.1:6379> pfadd hll 002
19                       (integer) 1
20                       127.0.0.1:6379> pfcount hll
21                       (integer) 2

                    6.2.2、統計數據               

1                       pfcount key [key ...]
2 
3                       PFCOUNT key [key ...]
4                         summary: Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s).
5                         since: 2.8.9
6                         group: hyperloglog
7 
8                       127.0.0.1:6379> pfcount hll
9                       (integer) 2

                    6.2.3、合併數據

 1                       pfmerge destkey sourcekey [sourcekey...]
 2 
 3                       PFMERGE destkey sourcekey [sourcekey ...]
 4                         summary: Merge N different HyperLogLogs into a single one.
 5                         since: 2.8.9
 6                         group: hyperloglog
 7 
 8                       127.0.0.1:6379> pfmerge hll-dest hll
 9                       OK
10                       127.0.0.1:6379> pfcount hll-dest
11                       (integer) 2

                    6.2.4、Tips 22:Redis 應用於獨立資訊統計。

                    6.2.5、相關說明

                          用於進行基數統計,不是集合,不保存數據,只記錄數量而不是具體數據。

                          核心是基數估算演算法,最終數值存在一定誤差。

                          誤差範圍:基數估計的結果是一個帶有0.81%標準錯誤的近似值。

                          消耗空間極小,每個 hyperloglog 佔用 12k 的記憶體用於標記基數。

                          pfadd 命令不是一次性分配 12k 記憶體使用,會隨著基數的增加記憶體逐漸增大。

                          pfmerge 命令合併後佔用的存儲空間為 12k,無論合併之前數據量是多少。

              6.3、GEO(只計算水平位置)

                    6.3.1、添加坐標點

 1                     GEOADD key longitude latitude member [longitude latitude member ...]
 2                       summary: Add one or more geospatial items in the geospatial index represented using a sorted set
 3                       since: 3.2.0
 4                       group: geo
 5 
 6 
 7                     127.0.0.1:6379> geoadd geos 1 1 shanghai
 8                     (integer) 1
 9                     127.0.0.1:6379> geoadd geos 2 2 guangdong
10                     (integer) 1

                    6.3.2、獲取坐標點

 1                     GEOPOS key member [member ...]
 2                       summary: Returns longitude and latitude of members of a geospatial index
 3                       since: 3.2.0
 4                       group: geo
 5 
 6 
 7                     127.0.0.1:6379> geopos geos shanghai
 8                     1) 1) "0.99999994039535522"
 9                        2) "0.99999945914297683"
10 
11                     127.0.0.1:6379> geopos geos guangdong
12                     1) 1) "2.00000256299972534"
                 2) "2.0000001856465488"

                    6.3.3、計算坐標點距離

 1                     GEODIST key member1 member2 [m|km|ft|mi]
 2                       summary: Returns the distance between two members of a geospatial index
 3                       since: 3.2.0
 4                       group: geo
 5                
 6                     127.0.0.1:6379> geodist geos shanghai guangdong
 7                     "157270.0561"
 8                     127.0.0.1:6379> geodist geos shanghai guangdong m(米)
 9                     "157270.0561"
10                     127.0.0.1:6379> geodist geos shanghai guangdong km(千米)
11                     "157.2701"
12                     127.0.0.1:6379> geodist geos shanghai guangdong ft
13                     "515977.8743"
14                     127.0.0.1:6379> geodist geos shanghai guangdong mi
15                     "97.7233"

                    6.3.4、根據坐標計算範圍內的數據(移動的坐標使用這個)

 1                     GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
 2                       summary: Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point
 3                       since: 3.2.0
 4                       group: geo
 5                
 6                     準備數據:
 7                     127.0.0.1:6379> geoadd geos 1 1 1,1
 8                     (integer) 1
 9                     127.0.0.1:6379> geoadd geos 1 2 1,2
10                     (integer) 1
11                     127.0.0.1:6379> geoadd geos 1 3 1,3
12                     (integer) 1
13                     127.0.0.1:6379> geoadd geos 2 1 2,1
14                     (integer) 1
15                     127.0.0.1:6379> geoadd geos 2 2 2,2
16                     (integer) 1
17                     127.0.0.1:6379> geoadd geos 2 3 2,3
18                     (integer) 1
19                     127.0.0.1:6379> geoadd geos 3 1 3,1
20                     (integer) 1
21                     127.0.0.1:6379> geoadd geos 3 2 3,2
22                     (integer) 1
23                     127.0.0.1:6379> geoadd geos 3 3 3,3
24                     (integer) 1
25                     127.0.0.1:6379> geoadd geos 5 5 5,5
26                     (integer) 1
27 
28                     127.0.0.1:6379> georadius geos 1.5 1.6 90 km
29                     1) "1,2"
30                     2) "2,2"
31                     3) "1,1"
32                     4) "2,1"

 
                    6.3.5、根據點求範圍內數據(靜止不動的坐標使用這個)

 1                     GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
 2                       summary: Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member
 3                       since: 3.2.0
 4                       group: geo
 5 
 6                     準備數據:
 7                     127.0.0.1:6379> geoadd geos 1 1 1,1
 8                     (integer) 1
 9                     127.0.0.1:6379> geoadd geos 1 2 1,2
10                     (integer) 1
11                     127.0.0.1:6379> geoadd geos 1 3 1,3
12                     (integer) 1
13                     127.0.0.1:6379> geoadd geos 2 1 2,1
14                     (integer) 1
15                     127.0.0.1:6379> geoadd geos 2 2 2,2
16                     (integer) 1
17                     127.0.0.1:6379> geoadd geos 2 3 2,3
18                     (integer) 1
19                     127.0.0.1:6379> geoadd geos 3 1 3,1
20                     (integer) 1
21                     127.0.0.1:6379> geoadd geos 3 2 3,2
22                     (integer) 1
23                     127.0.0.1:6379> geoadd geos 3 3 3,3
24                     (integer) 1
25                     127.0.0.1:6379> geoadd geos 5 5 5,5
26                     (integer) 1
27 
28                     127.0.0.1:6379> georadiusbymember geos 2,2 180 km
29                     1) "1,1"
30                     2) "2,1"
31                     3) "1,2"
32                     4) "2,2"
33                     5) "3,1"
34                     6) "3,2"
35                     7) "1,3"
36                     8) "2,3"
37                     9) "3,3"
38                     127.0.0.1:6379> georadiusbymember geos 2,2 120 km
39                     1) "1,2"
40                     2) "2,2"
41                     3) "2,3"
42                     4) "2,1"
43                     5) "3,2"
44                     127.0.0.1:6379> georadiusbymember geos 2,2 1800 km
45                      1) "1,1"
46                      2) "2,1"
47                      3) "1,2"
48                      4) "2,2"
49                      5) "3,1"
50                      6) "3,2"
51                      7) "1,3"
52                      8) "2,3"
53                      9) "3,3"
54                     10) "5,5"

                    6.3.6、獲取指定點對應坐標的hash值。

 1                     GEOHASH key member [member ...]
 2                       summary: Returns members of a geospatial index as standard geohash strings
 3                       since: 3.2.0
 4                       group: geo
 5                
 6                     127.0.0.1:6379> geohash geos 1,1
 7                     1) "s00twy01mt0"
 8                     127.0.0.1:6379> geohash geos 2,2
 9                     1) "s037ms06g70"
10                     127.0.0.1:6379> geohash geos 2,3
11                     1) "s093jd0k720"        

四、結束

        好了,今天就寫到這裡了。其實這篇文章寫了很久了,由於裡面涉及的內容比較多,所以這個過程還是很煎熬的。如果大家看過我以前的文章,就會知道,我以前也寫過一個有關Redis系列的文章,而且寫的也很詳細。這篇文章算是自己的回顧,也加上了自己對Redis的使用見解,當然環境從獨立物理伺服器搬到了Docker裡面,有關他的配置和在單獨伺服器上是有所不同的。學無止境,我還要繼續努力。每天進步一點點,不忘初心,繼續努力。