一、介绍

        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升级到最新版本 》【https://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": ["https://5f2jam6c.mirror.aliyuncs.com", "http://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里面,有关他的配置和在单独服务器上是有所不同的。学无止境,我还要继续努力。每天进步一点点,不忘初心,继续努力。


posted on 2021-04-11 11:52  可均可可  阅读(1257)  评论(3编辑  收藏  举报