阅读 108

庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存

一、介绍

        1、开始说明
        在微服务器架构中,有一个组件是不能少的,那就是缓存组件。其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能。我就不隐瞒了,今天我们要探讨的就是Redis,作为RDBMS的一个有效的补充。现在的互联网和以前的互联网已经发生了翻天覆地的变化,这些变化的突出特征就是“三高”。当然,这“三高”不是我们人类身体的三高,而是最新系统的三种特性,它们分别适合:高并发,高性能和高可用。这三种特征是现在系统必须满足的要求。为了满足这三个要求,其实会有很多技术来支持,但是里面有一个功能是必不可少的,那就是具有缓存功能和分布特性的Redis,它可以为这三个特性增光添彩,今天我们就来看看它的真面目,让我们对它有一个更全面、更直接的认识,深度我不敢说,因为自己也是在学习的过程中,如果以后有了新的体验,再和大家分享吧。

        2、基础环境

                2.1、操作系统:CentOs7(64bit)

        2.2、虚拟容器:Docker 19.03.13

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

        2.4、虚拟系统:VMware Workstation Pro 14.1.3

        2.5、Redis版本:6.2.1(最新版本)
    
        3、docker 环境安装

              3.1、直接执行命令,安装 Docker 就好。

                    命令:#yum install docker

              3.2、升级 docker 为最新的版本。

                    如果大家不熟悉,可以查看我写的文章《如何将Docker升级到最新版本 》【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.service10                        ├─1056 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock11                        └─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...grpc14                 2月 23 12:39:55 localhost147 dockerd[1056]: time="2021-02-23T12:39:55.385056316+08:00" level=info msg="Clie...grpc15                 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.320                 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 redis2                     Using default tag: latest3                     latest: Pulling from library/redis4                     Digest: sha256:0f97c1c9daf5b69b93390ccbe8d3e2971617ec4801fd0882c72bf7cad3a134945                     Status: Image is up to date for redis:latest6                     docker.io/library/redis:latest

复制代码


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

1                     [root@localhost147 ~]# docker images2                     REPOSITORY   TAG       IMAGE ID       CREATED       SIZE3                     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 yes2 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.conf4 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 yes6 7                       命令:#docker run --name redis02 -p 6380:6379 -d redis redis-server8                       命令:#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 -a2                        CONTAINER ID   IMAGE          COMMAND                  CREATED      STATUS          PORTS      NAMES3                        16e827f0f530   redis:latest   "docker-entrypoint.s…"   5 days ago   Up 20 minutes   6379/tcp   nifty_pare4                        [root@localhost147 ~]#

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

1                       [root@localhost147 ~]# docker ps2                       CONTAINER ID   IMAGE          COMMAND                  CREATED      STATUS          PORTS      NAMES3                       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/bash2                       root@16e827f0f530:/data# redis-cli3                       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: 110                     2021-02-21T07:00:08.126025129Z   `-._    `-._  `-./  _.-'    _.-'11                     2021-02-21T07:00:08.126051128Z  |`-._`-._    `-.__.-'    _.-'_.-'|12                     2021-02-21T07:00:08.126061728Z  |    `-._`-._        _.-'_.-'    |           http://redis.io13                     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.126186853Z21                     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 initialized23                     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.1026                     2021-02-21T07:00:08.127050705Z 1:M 21 Feb 2021 07:00:08.126 * RDB age 4015 seconds27                     2021-02-21T07:00:08.127061365Z 1:M 21 Feb 2021 07:00:08.126 * RDB memory usage when created 0.77 Mb28                     2021-02-21T07:00:08.127070425Z 1:M 21 Feb 2021 07:00:08.126 * DB loaded from disk: 0.002 seconds29                     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=always2                      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 key3                         since: 1.0.04                         group: string5 6 7                       127.0.0.1:6379> set name patrickliu8                        OK

复制代码


                    2.2.2、get key

复制代码

1                       GET key2                         summary: Get the value of a key3                         since: 1.0.04                         group: string5 6 7                       127.0.0.1:6379> get name8                        "patrickliu"

复制代码


                    2.2.3、del key

复制代码

1                       DEL key [key ...]2                         summary: Delete a key3                         since: 1.0.04                         group: generic5 6 7                       127.0.0.1:6379> del name8                         (integer) 1(1、表示删除成功)

复制代码

                    2.2.4、mset key1 value1 key2 value2 ...

复制代码

1                       MSET key value [key value ...]2                         summary: Set multiple keys to multiple values3                         since: 1.0.14                         group: string5 6                       127.0.0.1:6379> mset name liulei age 33 sex mail7                        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 key2                         summary: Get the length of the value stored in a key3                         since: 2.2.04                         group: string5 6 7                       127.0.0.1:6379> strlen name8                         (integer) 6(6、表示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) 1010                       127.0.0.1:6379> get name11                       "liuleiking"12 13 14                       【没有则新建】15                       127.0.0.1:6379> append xiong huangfeihong16                       (integer) 1217                       127.0.0.1:6379> get xiong18                       "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) 3410                       127.0.0.1:6379> incr age11                       (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 510                       (integer) 4011                       127.0.0.1:6379> incrby age 612                       (integer) 4613                       127.0.0.1:6379> incrby age -614                       (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.3410                       "64.34"11                       127.0.0.1:6379> incrbyfloat price 0.4312                       "64.77"13                       127.0.0.1:6379> incrbyfloat price -0.4314                       "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) 3910                       127.0.0.1:6379> decr age11                       (integer) 3812                       127.0.0.1:6379> decr age13                       (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 510                       (integer) 3211                       127.0.0.1:6379> decrby age 512                       (integer) 2713                       127.0.0.1:6379> decrby age 514                       (integer) 2215                       127.0.0.1:6379> decrby age -516                       (integer) 2717                       127.0.0.1:6379> decrby age -518                       (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 dog11                       (nil)12 13                       【ttl key,查询指定key剩余秒数】14                       127.0.0.1:6379> setex dog 6 tutu15                       OK16                       127.0.0.1:6379> ttl dog17                       (integer) 318                       127.0.0.1:6379> ttl dog19                       (integer) 120                       127.0.0.1:6379> ttl dog21                       (integer) 022                       127.0.0.1:6379> ttl dog23                       (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 dog11                       "tutu"12                       127.0.0.1:6379> get dog13                       "tutu"14                       127.0.0.1:6379> get dog15                       "tutu"16                       127.0.0.1:6379> get dog17                       "tutu"18                       127.0.0.1:6379> get dog19                       (nil)20 21                       127.0.0.1:6379> psetex dog 10000 tutu22                       OK23                       127.0.0.1:6379> pttl dog24                       (integer) 510825                       127.0.0.1:6379> pttl dog26                       (integer) 172227                       127.0.0.1:6379> pttl dog28                       (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 field3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hset user name liulei age 38 sex mail7                       (integer) 3

复制代码


                    2.3.3、hget key field

复制代码

1                       HGET key field2                         summary: Get the value of a hash field3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hget user name7                       "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 fields3                         since: 2.0.04                         group: hash5 6                 7                       127.0.0.1:6379> hdel user age sex8                       (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 fields3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hmget user name age sex7                       1) "liulei"8                       2) "33"9                       3) "male"

复制代码


                    2.3.8、hlen key

复制代码

1                       HLEN key2                         summary: Get the number of fields in a hash3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hlen user7                       (integer) 3

复制代码


                    2.3.9、hexists key field

复制代码

1                       HEXISTS key field2                         summary: Determine if a hash field exists3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hexists user age7                       (integer) 18                       127.0.0.1:6379> hexists user height9                       (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 key2                         summary: Get all the fields in a hash3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hkeys user7                       1) "name"8                       2) "age"9                       3) "sex"

复制代码


                    2.3.12、hvals key

复制代码

1                       HVALS key2                         summary: Get all the values in a hash3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hvals user7                       1) "liulei"8                       2) "33"9                       3) "male"

复制代码


                    2.3.13、hincrby key field increment

复制代码

1                       HINCRBY key field increment2                         summary: Increment the integer value of a hash field by the given number3                         since: 2.0.04                         group: hash5 6                       127.0.0.1:6379> hincrby user age 57                       (integer) 388                       127.0.0.1:6379> hincrby user age -59                       (integer) 33

复制代码


                    2.3.14、hincrbyfloat key field increment

复制代码

1                       HINCRBYFLOAT key field increment2                         summary: Increment the float value of a hash field by the given amount3                         since: 2.6.04                         group: hash5                6                       127.0.0.1:6379> hincrbyfloat user age 4.67                       "37.6"8                       127.0.0.1:6379> hincrbyfloat user age -4.69                       "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 list3                         since: 1.0.04                         group: list5 6                       127.0.0.1:6379> lpush user a b c7                       (integer) 3

复制代码


                    2.4.3、rpush key value1,value2...

复制代码

1                       RPUSH key element [element ...]2                         summary: Append one or multiple elements to a list3                         since: 1.0.04                         group: list5 6                       127.0.0.1:6379> lpush user a b c7                       (integer) 38                       127.0.0.1:6379> rpush user e f g9                       (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 index2                         summary: Get an element from a list by its index3                         since: 1.0.04                         group: list5 6                       127.0.0.1:6379> lindex user 47                       "f"

复制代码


                    2.4.6、llen key

复制代码

1                       LLEN key2                         summary: Get the length of a list3                         since: 1.0.04                         group: list5 6                       127.0.0.1:6379> llen user7                       (integer) 6

复制代码


                    2.4.7、lpop key

复制代码

1                       LPOP key2                         summary: Remove and get the first element in a list3                         since: 1.0.04                         group: list5 6                       127.0.0.1:6379> lpop user7                       "c"8                       127.0.0.1:6379> lpop user9                       "b"

复制代码


                    2.4.8、rpop key

复制代码

1                       RPOP key2                         summary: Remove and get the last element in a list3                         since: 1.0.04                         group: list5     6                       127.0.0.1:6379> rpop user7                       "g"8                       127.0.0.1:6379> rpop user9                       "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 510                       1) "user"11                       2) "c"12                       127.0.0.1:6379> blpop user 513                       1) "user"14                       2) "b"15                       127.0.0.1:6379> blpop user 516                       1) "user"17                       2) "a"18                       127.0.0.1:6379> blpop user 519 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 510                       1) "user"11                       2) "b"12                       127.0.0.1:6379> brpop user 513                       1) "user"14                       2) "c"15                       127.0.0.1:6379> brpop user 516                       1) "user"17                       2) "d"18                       127.0.0.1:6379> brpop user 519                       【有段时间等待】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 c16                       (integer) 117                       127.0.0.1:6379> lrange user 0 -118                       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) 110                       127.0.0.1:6379> sadd shuihu linchong11                       (integer) 112                       127.0.0.1:6379>

复制代码


                    2.5.3、smembers key

复制代码

1                       SMEMBERS key2                         summary: Get all the members in a set3                         since: 1.0.04                         group: set5 6                       127.0.0.1:6379> smembers shuihu7                       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 key2                         summary: Get the number of members in a set3                         since: 1.0.04                         group: set5 6 7                       127.0.0.1:6379> scard shuihu8                       (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 wusong11                       (integer) 1

复制代码


                    扩展操作:

                    2.5.8、srandmember key [count]

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


                    2.5.9、spop key [count]

1                       SPOP key [count]2                         summary: Remove and return one or multiple random members from a set3                         since: 1.0.04                         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 sets3                             since: 1.0.04                             group: set


                          2.5.10.2、sunion key1 [key2]

1                           SUNION key [key ...]2                             summary: Add multiple sets3                             since: 1.0.04                             group: set


                          2.5.10.3、sdiff key1 [key2]

1                           SDIFF key [key ...]2                             summary: Subtract multiple sets3                             since: 1.0.04                             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 key3                             since: 1.0.04                             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 key3                             since: 1.0.04                             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 key3                             since: 1.0.04                             group: set


                    2.5.12、将指定数据从原实际和中移动到目标集合中。

复制代码

1                       smove source destination member2 3                       SMOVE source destination member4                         summary: Move a member from one set to another5                         since: 1.0.06                         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 wangwu11                       (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 score3                         since: 1.0.54                         group: sorted_set5 6                       127.0.0.1:6379> zrangebyscore user 50 60 withscores7                       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 max2                       summary: Remove all members in a sorted set within the given scores3                       since: 1.2.04                       group: sorted_set5                    6                     127.0.0.1:6379> zremrangebyscore user 80 907                     (integer) 1

复制代码


                       2.6.10、注意:
                            。min与max用于限定搜索查询的条件。
                            。start与stop用于限定查询范围,作用于索引,表示开始和结束索引。
                            。offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量。

                       2.6.11、zcard key

复制代码

1                       ZCARD key2                         summary: Get the number of members in a sorted set3                         since: 1.2.04                         group: sorted_set5 6                       127.0.0.1:6379> zcard user7                       (integer) 3

复制代码


                       2.6.12、zcount key min max

复制代码

1                       ZCOUNT key min max2                         summary: Count the members in a sorted set with scores within the given values3                         since: 2.0.04                         group: sorted_set5                      6                       127.0.0.1:6379> zcount user 50 907                       (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 key3                         since: 2.0.04                         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 key3                       since: 2.0.04                       group: sorted_set


                    扩展操作(适合榜单排行)

                       2.6.15、zrank key member

复制代码

1                       ZRANK key member2                         summary: Determine the index of a member in a sorted set3                         since: 2.0.04                         group: sorted_set5 6                       127.0.0.1:6379> zrank user liubei7                       (integer) 0

复制代码


                       2.6.16、zrevrank key member

复制代码

1                       ZREVRANK key member2                         summary: Determine the index of a member in a sorted set, with scores ordered from high to low3                         since: 2.0.04                         group: sorted_set5 6                       127.0.0.1:6379> zrevrank user liubei7                       (integer) 3

复制代码


                       2.6.17、zscore key member

复制代码

1                       ZSCORE key member2                         summary: Get the score associated with the given member in a sorted set3                         since: 1.2.04                         group: sorted_set5 6                       127.0.0.1:6379> zscore user guanyu7                       (nil)8                       127.0.0.1:6379> zscore user liubei9                       "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 withscores10                       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 key3                       since: 1.0.04                       group: generic5                 6                     127.0.0.1:6379> del name7                     (integer) 1

复制代码


                      3.1.2、exists key

复制代码

1                     EXISTS key [key ...]2                       summary: Determine if a key exists3                       since: 1.0.04                       group: generic5 6                     127.0.0.1:6379> exists name7                     (integer) 1

复制代码


                    3.1.3、type key

复制代码

1                     TYPE key2                       summary: Determine the type stored at key3                      since: 1.0.04                       group: generic5 6                     127.0.0.1:6379> set name liulei7                     OK                
8                     127.0.0.1:6379> type name9                     string

复制代码


            3.2、key的扩展操作(时效性控制)

                    3.2.1、expire key seconds

1                     EXPIRE key seconds2                       summary: Set a key's time to live in seconds3                       since: 1.0.04                       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 key2                       summary: Get the time to live for a key3                       since: 1.0.04                       group: generic

                    3.2.4、pttl key

1                     PTTL key2                       summary: Get the time to live for a key in milliseconds3                       since: 2.6.04                       group: generic

                    3.2.5、persist key

1                     PERSIST key2                       summary: Remove the expiration from a key3                       since: 2.2.04                       group: generic


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

                    3.3.1、keys *

1                     keys *3                     keys it5                     keys *myjob


                    3.3.2、keys ?

1                     keys ??feihong 3                     keys bao?a5                     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 newkey2                       summary: Rename a key3                       since: 1.0.04                       group: generic


                    3.4.2、renamenx key newkey

1                   RENAMENX key newkey2                     summary: Rename a key, only if the new key does not exist3                     since: 1.0.04                     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 set3                     since: 1.0.04                     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 available101               since: not known102 103               XSETID key arg104               summary: Help not available105               since: not known106 107               BITFIELD_RO key ...options...108               summary: Help not available109               since: not known110 111               SUBSTR key arg arg112               summary: Help not available113               since: not known114 115               GEORADIUS_RO key arg arg arg arg ...options...116               summary: Help not available117               since: not known118 119               PFSELFTEST120               summary: Help not available121               since: not known122 123               ASKING124               summary: Help not available125               since: not known126 127               RESTORE-ASKING key arg arg ...options...128               summary: Help not available129               since: not known130 131               PFDEBUG arg arg ...options...132               summary: Help not available133               since: not known134 135               GEORADIUSBYMEMBER_RO key arg arg arg ...options...136               summary: Help not available137               since: not known138 139               POST ...options...140               summary: Help not available141               since: not known142 143               REPLCONF ...options...144               summary: Help not available145               since: not known

复制代码


            3.5、db 的基本操作

                    3.5.1、select index

复制代码

1                      SELECT index2                       summary: Change the selected database for the current connection3                       since: 1.0.04                       group: connection5 6                     127.0.0.1:6379> select 17                     OK8                     127.0.0.1:6379[1]>

复制代码


                    3.5.2、quit

1                     QUIT -2                       summary: Close the connection3                       since: 1.0.04                       group: connection


                    3.5.3、ping

复制代码

1                     PING [message]2                       summary: Ping the server3                       since: 1.0.04                       group: connection5 6                     127.0.0.1:6379> ping7                     PONG8                     127.0.0.1:6379> ping huangfeihong9                     "huangfeihong"

复制代码


                    3.5.4、echo

复制代码

1                     ECHO message2                       summary: Echo the given string3                       since: 1.0.04                       group: connection5 6                     127.0.0.1:6379> echo nihao7                     "nihao"

复制代码


            3.6、db 的相关操作

                    3.6.1、move key db

1                     MOVE key db2                         summary: Move a key to another database3                         since: 1.0.04                         group: generic


                    3.6.2、dbsize

复制代码

1                     DBSIZE -2                       summary: Return the number of keys in the selected database3                       since: 1.0.04                       group: server5   6 7                     127.0.0.1:6379> dbsize8                     (integer) 0

复制代码


                    3.6.3、flushdb

复制代码

1                     FLUSHDB [ASYNC]2                       summary: Remove all keys from the current database3                       since: 1.0.04                       group: server5 6                     127.0.0.1:6379> flushdb7                     OK

复制代码


                    3.6.4、flushall

复制代码

1                   FLUSHALL [ASYNC]2                     summary: Remove all keys from all databases3                     since: 1.0.04                     group: server5 6                   127.0.0.1:6379> flushall7                   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 ls10 11                   [root@localhost147 redis]# docker container ls12                   CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES13                   5ea80b52539f   redis     "docker-entrypoint.s…"   29 minutes ago   Up 29 minutes   0.0.0.0:6381->6379/tcp   redis0314                   a86b55a8df2f   redis     "docker-entrypoint.s…"   30 minutes ago   Up 30 minutes   0.0.0.0:6380->6379/tcp   redis0215                   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> bgrewriteaof2                           Background append only file rewriting started


                          2.3.6.2、自动重写

                                2.3.6.2.1、自动重写触发条件设置

1                                 auto-aof-rewrite-min-size size2                                 自动重写最小值3 4                                 auto-aof-rewrite-percentage percent5                                 自动重写百分比


                                2.3.6.2.2、自动重写触发对比参数

1                                 aof_current_size2                                 在缓冲区中当前数据的大小3 4                                 aof_base_size5                                 基础大小


                                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                     QUEUED10                     127.0.0.1:6379> get name11                     QUEUED12                     127.0.0.1:6379> exec13                     1) OK14                     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                     QUEUED10                     127.0.0.1:6379> get age11                     QUEUED12                     127.0.0.1:6379> discard13                     OK14                     127.0.0.1:6379> exec15                     (error) ERR EXEC without MULTI16                     127.0.0.1:6379>

复制代码


                    4.2.3、exec 执行事务

1                     EXEC -2                       summary: Execute all commands issued after MULTI3                       since: 1.2.04                       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                     OK10                     127.0.0.1:6379> watch name age11                     OK12                     127.0.0.1:6379> multi13                     OK14                     127.0.0.1:6379> incr age15                     QUEUED16                     127.0.0.1:6379> get name17                     QUEUED18                     127.0.0.1:6379> exec19                     1) (integer) 3420                     2) "liulei"

复制代码


                    4.3.2、unwatch

复制代码

1                     UNWATCH -2                       summary: Forget about all watched keys3                       since: 2.2.04                       group: transactions5 6                     127.0.0.1:6379> unwatch7                     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) 010                     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 stats2                       # Stats    
3                       keyspace_hits:14                       keyspace_misses:0


        6、高级数据类型

              6.1、Bitmaps(统计状态:性别,好坏,看与不看等等,就两个状态,是或者否)

                    6.1.1、getbit key offset

复制代码

1                       GETBIT key offset2                         summary: Returns the bit value at offset in the string value stored at key3                         since: 2.2.04                         group: string5 6                       127.0.0.1:6379> getbit bits 07                       (integer) 1

复制代码


                    6.1.2、SETBIT key offset value

复制代码

1                       SETBIT key offset value2                         summary: Sets or clears the bit at offset in the string value stored at key3                         since: 2.2.04                         group: string5 6                       127.0.0.1:6379> setbit bits 0 17                       (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 115                       (integer) 016                       127.0.0.1:6379> setbit 20880808 4 117                       (integer) 018                       127.0.0.1:6379> setbit 20880808 8 119                       (integer) 020                       127.0.0.1:6379> setbit 20880809 0 121                       (integer) 122                       127.0.0.1:6379> setbit 20880809 5 123                       (integer) 024                       127.0.0.1:6379> setbit 20880809 8 125                       (integer) 126 27                       127.0.0.1:6379> bitop or 08-09 20880808 2088080928                       (integer) 229 30                       127.0.0.1:6379> bitcount 08-0931                       (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) 010                       127.0.0.1:6379> setbit 20880808 8 111                       (integer) 012                       127.0.0.1:6379> setbit 20880809 0 113                       (integer) 114                       127.0.0.1:6379> setbit 20880809 5 115                       (integer) 016                       127.0.0.1:6379> setbit 20880809 8 117                       (integer) 118 19                       127.0.0.1:6379> bitcount 2088080920                       (integer) 321                       127.0.0.1:6379> bitcount 2088080822                       (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) 110                       127.0.0.1:6379> pfadd hll 00111                       (integer) 012                       127.0.0.1:6379> pfadd hll 00113                       (integer) 014                       127.0.0.1:6379> pfadd hll 00115                       (integer) 016                       127.0.0.1:6379> pfadd hll 00117                       (integer) 018                       127.0.0.1:6379> pfadd hll 00219                       (integer) 120                       127.0.0.1:6379> pfcount hll21                       (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.96                         group: hyperloglog7 8                       127.0.0.1:6379> pfcount hll9                       (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                       OK10                       127.0.0.1:6379> pfcount hll-dest11                       (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 guangdong10                     (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 guangdong12                     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 ft13                     "515977.8743"14                     127.0.0.1:6379> geodist geos shanghai guangdong mi15                     "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,210                     (integer) 111                     127.0.0.1:6379> geoadd geos 1 3 1,312                     (integer) 113                     127.0.0.1:6379> geoadd geos 2 1 2,114                     (integer) 115                     127.0.0.1:6379> geoadd geos 2 2 2,216                     (integer) 117                     127.0.0.1:6379> geoadd geos 2 3 2,318                     (integer) 119                     127.0.0.1:6379> geoadd geos 3 1 3,120                     (integer) 121                     127.0.0.1:6379> geoadd geos 3 2 3,222                     (integer) 123                     127.0.0.1:6379> geoadd geos 3 3 3,324                     (integer) 125                     127.0.0.1:6379> geoadd geos 5 5 5,526                     (integer) 127 28                     127.0.0.1:6379> georadius geos 1.5 1.6 90 km29                     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,210                     (integer) 111                     127.0.0.1:6379> geoadd geos 1 3 1,312                     (integer) 113                     127.0.0.1:6379> geoadd geos 2 1 2,114                     (integer) 115                     127.0.0.1:6379> geoadd geos 2 2 2,216                     (integer) 117                     127.0.0.1:6379> geoadd geos 2 3 2,318                     (integer) 119                     127.0.0.1:6379> geoadd geos 3 1 3,120                     (integer) 121                     127.0.0.1:6379> geoadd geos 3 2 3,222                     (integer) 123                     127.0.0.1:6379> geoadd geos 3 3 3,324                     (integer) 125                     127.0.0.1:6379> geoadd geos 5 5 5,526                     (integer) 127 28                     127.0.0.1:6379> georadiusbymember geos 2,2 180 km29                     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 km39                     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 km45                      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,311                     1) "s093jd0k720"        

复制代码



四、结束

        好了,今天就写到这里了。其实这篇文章写了很久了,由于里面涉及的内容比较多,所以这个过程还是很煎熬的。如果大家看过我以前的文章,就会知道,我以前也写过一个有关Redis系列的文章,而且写的也很详细。这篇文章算是自己的回顾,也加上了自己对Redis的使用见解,当然环境从独立物理服务器搬到了Docker里面,有关他的配置和在单独服务器上是有所不同的。学无止境,我还要继续努力。每天进步一点点,不忘初心,继续努力。


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐