Redis知识总结

本文深入讲解Redis的基础概念、数据类型及其应用场景,涵盖安装配置、内存管理、持久化策略等内容,适合初学者快速掌握Redis的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Redis是简介

​ Redis 是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。(Vmware在资助着redis项目的开发和维护)

BSD是"Berkeley Software Distribution"的缩写,意思是"伯克利软件发行版"。

BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。BSD代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。

2.NoSQL介绍

     NOSQL:非关系型数据库,数据与数据之间没有关联关系

     SQL:关系型数据库,表与表之间建立关联关系

NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

NoSQL数据库的四大分类

键值(Key-Value)存储数据库

这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。 举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.

列存储数据库

这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.文档型数据库 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。

图形(Graph)数据库

图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph.

因此,我们总结NoSQL数据库在以下的这几种情况下比较适用:

      1、数据模型比较简单;

       2、需要灵活性更强的IT系统;

       3、对数据库性能要求较高;

       4、不需要高度的数据一致性;

       5、对于给定key,比较容易映射复杂值的环境。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

  • Redis支持数据的备份,集群等高可用功能。

特点:

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

  • 丰富的数据类型 – Redis支持的类型 String, List, Hash, Set 及 Ordered Set 数据类型操作。

  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis是一个简单的,高效的,分布式的,基于内存的缓存工具。 架设好服务器后,通过网络连接(类似数据库),提供Key-Value式缓存服务。简单,是Redis突出的特色。 简单可以保证核心功能的稳定和优异。

Redis总结

redis单个key 存入512M大小

redis支持多种类型的数据结构(string,list,hash.set.zset)

redis 是单线程 原子性

redis可以持久化 因为使用了 RDB和AOF机制

redis支持集群 而且redis 支持库(0-15) 16个库

redis 还可以做消息队列 比如聊天室 IM

企业级开发中:可以用作数据库、缓存(热点数据(经常会被查询,但是不经常被修改或者删除的数据)和消息中间件等大部分功能。

优点:

  1. 丰富的数据结构

    2 . 高速读写,redis使用自己实现的分离器,代码量很短,没有使用lock(MySQL),因此效率非常高。

缺点:

  1. 持久化。Redis直接将数据存储到内存中,要将数据保存到磁盘上,Redis可以使用两种方式实现持久化过程。定时快照(snapshot):每隔一段时间将整个数据库写到磁盘上,每次均是写全部数据,代价非常高。第二种方式基于语句追加(aof):只追踪变化的数据,但是追加的log可能过大,同时所有的操作均重新执行一遍,回复速度慢。

  2. 耗内存,占用内存过高。

3.Redis安装

Linux安装

安装Redis

官方网站:http://redis.io/

官方下载:http://redis.io/download 可以根据需要下载不同版本

(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)

Redis安装

Redis是C语言开发,安装Redis需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc

安装gcc,gcc的安装很简单,首先要确保root登录,其次就是Linux要能连外网

注意:运行yum时出现/var/run/yum.pid已被锁定,PID为xxxx的另一个程序正在运行的问题解决

安装Redis

命令1: wget http://download.redis.io/releases/redis-4.0.1.tar.gz

命令2:tar zxvf redis-4.0.1.tar.gz

命令3: cd redis-4.0.1

命令4(编译): make 或 make MALLOC=libc 如下图代表成功:

 

命令5:make PREFIX=/usr/local/redis install

(安装编译后的文件) 安装到指目录:

注意:PREFIX必须大写、同时会自动为我们创建redis目录,并将结果安装此目录

命令6: cd /usr/local/redis 查看

命令7:查看bin目录下,如图:

 

Redis启动

启动Redis服务

进入对应的安装目录 /usr/local/redis

执行命令: ./bin/redis-server

 

启动Redis客户端

进入Redis客服端(Clone Session克隆一个窗口):

进入对应的安装目录 cd /usr/local/redis

执行命令: ./bin/redis-cli

 

启动Redis 客户端命令:

redis-cli –h IP地址 –p 端口

退出客户端命令:Ctrl+C

检测是否服务端启动

启动 redis 客户端,打开终端并输入命令 redis-cli。该命令会连接本地的 redis 服务。

$redis-cli

redis 127.0.0.1:6379>

redis 127.0.0.1:6379> PING

PONG

在以上实例中我们连接到本地的 redis 服务并执行 PING 命令,该命令用于检测 redis 服务是否启动。

4.Linux配置Redis

Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf)。

配置Redis

Redis端口号或启动有默认配置。但一般我们都会通过手动配置完成

回到根目录找到解压文件中的reids.conf

 

命令:cp redis.conf /usr/local/redis 将配置文件复制到安装文件的目录下

 

Redis配置至此全部完成

4.1redis.conf 配置文件详解 

     redis.conf 配置项说明如下:

  1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

​       daemonize no

     2.当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

       ​ pidfile /var/run/redis.pid

     3.指定Redis监听端口,默认端口为6379,为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而               MERZ取自意大利歌女Alessia Merz的名字

​       port 6379

     4.绑定的主机地址   bind 127.0.0.1

     5.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

​      timeout 300

    6.指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

​      loglevel verbose

     7.日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志       将会发送给/dev/null

​      logfile stdout

    8.设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id

​     databases 16

   9.指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

​       save <seconds> <changes>

​       Redis默认配置文件中提供了三个条件:

​       save 900 1

​       save 300 10

     ​ save 60 10000

​       分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。

    10.指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但            会导致数据库文件变的巨大

​     rdbcompression yes

   11.指定本地数据库文件名,默认值为dump.rdb

​        dbfilename dump.rdb

  12.指定本地数据库存放目录

​      dir ./

13.设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步

​     slaveof <masterip> <masterport>

14.当master服务设置了密码保护时,slav服务连接master的密码

​      masterauth <master-password>

15.设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭

​      requirepass foobared

16.设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符  数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

        ​ maxclients 128

17.指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区

       ​ maxmemory <bytes>

18.指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no

​       appendonly no

19.指定更新日志文件名,默认为appendonly.aof

     ​ appendfilename appendonly.aof

20.指定更新日志条件,共有3个可选值: no:表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) everysec:表示每秒同步一次(折中,默认值)

​      appendfsync everysec

21.指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)

​  vm-enabled no

22.虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享

​ vm-swap-file /tmp/redis.swap

23.将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0

​ vm-max-memory 0

24.Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值

​ vm-page-size 32

25.设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。

​ vm-pages 134217728

26.设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4

​ vm-max-threads 4

28.设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

​ glueoutputbuf yes

30.指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法

​ hash-max-zipmap-entries 64

​ hash-max-zipmap-value 512

31.指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)

​ activerehashing yes

  32.指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定        配  置文件

​ include /path/to/local.conf

5.Redis中的内存维护策略

redis作为优秀的中间缓存件,时常会存储大量的数据,即使采取了集群部署来动态扩容,也应该及时的整理内存,维持系统性能。

在redis中有两种解决方案

一是为数据设置超时时间,二是采用LRU算法动态将不用的数据删除。

内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据。

1.volatile-lru:设定超时时间的数据中,删除最不常使用的数据.

2.allkeys-lru:查询所有的key中最近最不常使用的数据进行删除,这是应用最广泛的策略.

3.volatile-random:在已经设定了超时的数据中随机删除.

4.allkeys-random:查询所有的key,之后随机删除.

5.volatile-ttl:查询全部设定超时时间的数据,之后排序,将马上将要过期的数据进行删除操作.

6.noeviction:如果设置为该属性,则不会进行删除操作,如果内存溢出则报错返回.

  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键

  • allkeys-lfu:从所有键中驱逐使用频率最少的键

https://www.jianshu.com/p/c8aeb3eee6bc

6.自定义配置Redis

1、进入对应的安装目录 /usr/local/redis

修改 redis.conf 配置文件 vim redis.conf (进入命令模式 通过/内容 查找相应字符串)

2、Redis配置默认必须修改:

daemonize no 修改为 daemonize yes

bind 127.0.01 注释掉

requirepass 设置密码

​ Redis采用的是单进程多线程的模式。当redis.conf中选项daemonize设置成yes时,代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。但当daemonize选项设置成no时,当前界面将进入redis的命令行界面,exit强制退出或者关闭连接工具(putty,xshell等)都会导致redis进程退出。服务端开发的大部分应用都是采用后台运行的模式

Redis启动:

服务端启动:  ./bin/redis-server ./redis.conf

客户端启动:本地客户端登录   用redis-cli 密码登陆(redis-cli -a password)

远程服务上执行命令 如果需要在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令。

语法:

redis-cli -h host -p port -a password

redis-cli –h IP地址 –p 端口 –a 密码

Redis关闭

第一种关闭方式:(断电、非正常关闭。容易数据丢失)

查询PID ps -ef | grep -i redis

kill -9 PID

第二种关闭方式(正常关闭、数据保存)

./bin/redis-cli shutdown 关闭redis服务,通过客户端进行shutdown

如果redis设置了密码,需要先在客户端通过密码登录,再进行shutdown即可关闭服务端

通过 ps –ef | grep –i redis 查看当前进程:

7.Redis命令描述

Redis 命令用于在 redis 服务上执行操作。要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)等

Redis键key

Redis 键命令用于管理 redis 的键

DEL key该命令用于在 key 存在时删除 key。DUMP key序列化给定 key ,并返回被序列化的值。

EXISTS key 检查给定 key 是否存在。EXPIRE key seconds为给定 key 设置过期时间(以秒计)。

PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。TTL key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live) PTTL key 以毫秒为单位返回 key 的剩余的过期时间。

PERSIST key 移除 key 的过期时间,key 将持久保持。

KEYS pattern 查找所有符合给定模式( pattern)的 key 。

keys 通配符 获取所有与pattern匹配的key,返回所有与该匹配

通配符:

​ * 代表所有

​ ? 表示代表一个字符

RENAME key newkey

修改Key的名称

MOVE key db 将当前数据库的 key 移动到给定的数据库 db 当中

TYPE key 返回 key 所储存的值的类型

应用场景

EXPIRE key seconds1、限时的优惠活动信息

2、网站数据缓存(对于一些需要定时更新的数据,例如:积分排行榜)

3、手机验证码

4、限制网站访客访问频率(例如:1分钟最多访问10次)

Key的命名建议

redis单个key 存入512M大小

1.key不要太长,尽量不要超过1024字节,这不仅消耗内存,而且会降低查找的效率;2.key也不要太短,太短的话,key的可读性会降低;3.在一个项目中,key最好使用统一的命名模式,例如user:123:password;

4.key名称区分大小写

8.Redis数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)等

8.1.List类型

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)

类似JAVA中的LinkedList

命令赋值语法:

LPUSH key value1 [value2] //将一个或多个值插入到列表头部(从左侧添加)

RPUSH key value1 [value2] //在列表中添加一个或多个值(从右侧添加)

LPUSHX key value //将一个值插入到已存在的列表头部。如果列表不在,操作无效

RPUSHX key value //一个值插入已存在的列表尾部(最右边)。如果列表不在,操作无效。

取值语法:

LLEN key //获取列表长度

LINDEX key index //通过索引获取列表中的元素

LRANGE key start stop //获取列表指定范围内的元素

描述: 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

start: 页大小*(页数-1)

stop : (页大小*页数)-1

删除语法:

LPOP key 移出并获取列表的第一个元素(从左侧删除)

RPOP key 移除列表的最后一个元素,返回值为移除的元素(从右侧删除)

BLPOP key1 [key2 ] timeout

移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

实例

redis 127.0.0.1:6379> BLPOP list1 100

在以上实例中,操作会被阻塞,如果指定的列表 key list1 存在数据则会返回第一个元素,否则在等待100秒后会返回 nil 。

BRPOP key1 [key2 ] timeout

移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

修改语法:

LSET key index value 通过索引设置列表元素的值

LINSERT key BEFORE|AFTER world value 在列表的元素前或者后插入元素

描述:将值 value 插入到列表 key 当中,位于值 world 之前或之后。

高级语法:

RPOPLPUSH source destination

移除列表的最后一个元素,并将该元素添加到另一个列表并返回 示例描述:

RPOPLPUSH a1 a2 //a1的最后元素移到a2的左侧

RPOPLPUSH a1 a1 //循环列表,将最后元素移到最左侧

BRPOPLPUSH source destination timeout

从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

应用场景

项目常应用于:1、对数据量大的集合数据删减 2、任务队列

  1. 对数据量大的集合数据删减

列表数据显示、关注列表、粉丝列表、留言评价等…分页、热点新闻(Top5)等

利用LRANGE还可以很方便的实现分页的功能,在博客系统中,每片博文的评论也可以存入一个单独的list中。

  1. 任务队列

(list通常用来实现一个消息队列,而且可以确保先后顺序,不必像MySQL那样还需要通过ORDER BY来进行排序)

任务队列介绍(生产者和消费者模式):

在处理Web客户端发送的命令请求时,某些操作的执行时间可能会比我们预期的更长一些,通过将待执行任务的相关信息放入队列里面,并在之后对队列进行处理,用户可以推迟执行那些需要一段时间才能能完成的操作,这种将工作交给任务处理器来执行的做法被称为任务队列(task queue)。

RPOPLPUSH source destination

移除列表的最后一个元素,并将该元素添加到另一个列表并返回 示例描述:

常用案例:

1:订单系统的下单流程、

2:用户系统登录注册短信等

用户登录成功后,

三个资源:

列表页面 (登录后就允许访问)

实名认证页面(登录后就允许访问)

转帐页面 (登录后、还要实名认证后)

代码演示:

8.2 Set类型

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

类似于JAVA中的 Hashtable集合

redis的集合对象set的底层存储结构特别神奇,底层使用了intset和hashtable两种数据结构存储的,intset我们可以理解为数组,hashtable就是普通的哈希表(key为set的值,value为null)。

intset内部其实是一个数组(int8_t coentents[]数组),而且存储数据的时候是有序的,因为在查找数据的时候是通过二分查找来实现的。

命令

赋值语法:

[SADD key member1 member2] 向集合添加一个或多个成员

取值语法:

SCARD key 获取集合的成员数

SMEMBERS key 返回集合中的所有成员

SISMEMBER key member 判断 member 元素是否是集合 key 的成员(开发中:验证是否存在判断)

[SRANDMEMBER key count] 返回集合中一个或多个随机数

删除语法:

SREM key member1 [member2] 移除集合中一个或多个成员

SPOP key [count] 移除并返回集合中的一个随机元素

SMOVE source destination member

将 member 元素从 source 集合移动到 destination 集合

差集语法:

[SDIFF key1 key2] 返回给定所有集合的差集(左侧)

SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中

交集语法:

[SINTER key1 key2] 返回给定所有集合的交集(共有数据)

SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中

并集语法:

[SUNION key1 key2] 返回所有给定集合的并集

SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中

应用场景

常应用于:对两个集合间的数据[计算]进行交集、并集、差集运算

1、以非常方便的实现如共同关注、共同喜好、二度好友等功能。对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存储到一个新的集合中。

2、利用唯一性,可以统计访问网站的所有独立 IP

8.3有序集合(sorted set) ZSET

1、 Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

2、不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

3、有序集合的成员是唯一的,但分数(score)却可以重复。

4、集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

Redis的ZSet是有序、且不重复

(很多时候,我们都将redis中的有序集合叫做zsets,这是因为在redis中,有序集合相关的操作指令都是以z开头的)

命令

赋值语法:

ZADD key score1 member1 [score2 member2]

向有序集合添加一个或多个成员,或者更新已存在成员的分数

取值语法:

ZCARD key 获取有序集合的成员数

ZCOUNT key min max 计算在有序集合中指定区间分数的成员数

ZRANK key member 返回有序集合中指定成员的索引

ZRANGE key start stop [WITHSCORES]

通过索引区间返回有序集合成指定区间内的成员(低到高)

ZREVRANGE key start stop [WITHSCORES]

返回有序集中指定区间内的成员,通过索引,分数从高到底

删除语法:

​ del key 移除集合

ZREM key member [member ...] 移除有序集合中的一个或多个成员

ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员(第一名是0)(低到高排序)

ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员

应用场景

常应用于:排行榜

1比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

2比如一个存储全班同学成绩的Sorted Set,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。

3还可以用Sorted Set来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。

String

string是redis最基本的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。

二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改、破译等,如果被攻击,能够及时检测出来

二进制安全特点:

​ 1、编码、解码发生在客户端完成,执行效率高

​ 2、不需要频繁的编解码,不会出现乱码

8.4String命令

赋值语法:

SET KEY_NAME VALUE

Redis SET 命令用于设置给定 key 的值。如果 key 已经存储值, SET 就覆写旧值,且无视类型

SETNX key value //解决分布式锁 方案之一

只有在 key 不存在时设置 key 的值。Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值

MSET key value [key value ...]

同时设置一个或多个 key-value 对

取值语法:

GET KEY_NAME

Redis GET命令用于获取指定 key 的值。如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误。

GETRANGE key start end

用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)

GETBIT key offset

对 key 所储存的字符串值,获取指定偏移量上的位(bit)

MGET key1 [key2..]

获取所有(一个或多个)给定 key 的值

GETSET语法: GETSET KEY_NAME VALUE

Getset 命令用于设置指定 key 的值,并返回 key 的旧值,当 key 不存在时,返回 nil

STRLEN key

返回 key 所储存的字符串值的长度

删除语法:

DEL KEY_Name

删除指定的KEY,如果存在,返回值数字类型。

自增/自减:

INCR KEY_Name

Incr 命令将 key 中储存的数字值增1。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作

自增:INCRBY KEY_Name 增量值

Incrby 命令将 key 中储存的数字加上指定的增量值

自减:DECR KEY_NAME 或 DECYBY KEY_NAME 减值

decR 命令将 key 中储存的数字减1

字符串拼接:APPEND KEY_NAME VALUE

Append 命令用于为指定的 key 追加至未尾,如果不存在,为其赋值

应用场景:

1、String通常用于保存单个字符串或JSON字符串数据

2、因String是二进制安全的,所以你完全可以把一个图片文件的内容作为字符串来存储

3、计数器(常规key-value缓存应用。常规计数: 微博数, 粉丝数)

INCR等指令本身就具有原子操作的特性,所以我们完全可以利用redis的INCR、INCRBY、DECR、DECRBY等指令来实现原子计数的效果。假如,在某种场景下有3个客户端同时读取了mynum的值(值为2),然后对其同时进行了加1的操作,那么,最后mynum的值一定是5。

不少网站都利用redis的这个特性来实现业务上的统计计数需求。

8.5哈希(Hash)

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)

可以看成具有KEY和VALUE的MAP容器,该类型非常适合于存储值对象的信息,

如:uname,upass,age等。该类型的数据仅占用很少的磁盘空间(相比于JSON)

Hash命令

赋值语法:

HSET KEY FIELD VALUE //为指定的KEY,设定FILD/VALUE

HMSET KEY FIELD VALUE [FIELD1,VALUE1]…… 同时将多个 field-value (域-值)对设置到哈希表 key 中。

取值语法:

HGET KEY FIELD //获取存储在HASH中的值,根据FIELD得到VALUE

HMGET key field[field1] //获取key所有给定字段的值

HGETALL key //返回HASH表中所有的字段和值

​HKEYS key //获取所有哈希表中的字段

HLEN key //获取哈希表中字段的数量

删除语法:

HDEL KEY field1[field2] //删除一个或多个HASH表字段

其它语法:

HSETNX key field value

只有在字段 field 不存在时,设置哈希表字段的值

HINCRBY key field increment

为哈希表 key 中的指定字段的整数值加上增量 increment 。

HINCRBYFLOAT key field increment

为哈希表 key 中的指定字段的浮点数值加上增量 increment 。

HEXISTS key field //查看哈希表 key 中,指定的字段是否存在

应用场景:

Hash的应用场景:(存储一个用户信息对象数据)

  1. 常用于存储一个对象

  2. 为什么不用string存储一个对象?

hash是最接近关系数据库结构的数据类型,可以将数据库一条记录或程序中一个对象转换成hashmap存放在redis中。

用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:

​ 第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。

​ 第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。

总结:

Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口

Java连接Redis

在官方网站列一些Java客户端访问,有:Jedis/Redisson/Jredis/JDBC-Redis等,其中官方推荐使用Jedis和Redisson。常用Jedis。

开始在 Java 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 Java redis 驱动,且你的机器上能正常使用 Java。 Java的安装配置可以参考我们的 Java开发环境配置 接下来让我们安装 Java redis 驱动

安装相应JAR:

 

开启端口防火墙

开放端口(如下命令只针对Centos7以上)

​ 查看已经开放的端口:firewall-cmd --list-ports

​ 开启端口:

​ firewall-cmd --zone=public --add-port=6379/tcp --permanent

重启防火墙

​ firewall-cmd --reload #重启

Java操作Redis 设置密码

 

这个问题是由于Redis没有配置密码的原因导致的,只需要为redis设置密码即可

config get requirepass: 这是查询redis是否配置密码,如果返回为空,则表明未配置密码

 

config set requirepass “guoweixin”这是将redis的密码设置为“guoweixin”

 

客户端登录:用redis-cli 密码登陆(redis-cli -a password)

Java Jedis连接池优化

 

 

案例:Jedis操作Redis string 和hash

 

----------------------------

 

RedisTemplate

简介

Spring data 提供了RedisTemplate模版

它封装了redis连接池管理的逻辑,业务代码无须关心获取,释放连接逻辑;spring redis同时支持了Jedis,Jredis,rjc 客户端操作;

在RedisTemplate中提供了几个常用的接口方法的使用,分别是

 

 

Spring data 使用RedisTemplate模版

1、jar:Redis和Spring整合

 

2、对应实体Bean进行序列化操作

 

3、编写相应配置文件利用RedisTemplate操作Redis

 

JedisPoolConfig常用配置信息

Redis客户端工具

https://redisdesktop.com/download

 

查看Redis客户端

 

原因 :把任何数据保存到redis中时,都需要进行序列化,默认使用JdkSerializationRedisSerializer进行数据序列化。

所有的key和value还有hashkey和hashvalue的原始字符前,都加了一串字符。

 

案例作业

限制登录功能

用户在2分钟内,仅允许输入错误密码5次。如果超过次数,限制其登录1小时。(要求每登录失败时,都要给相应提式)

基本代码1:

 

 

完整代码2

需求分析:

 

业务层编写

 

 

Controller层

 

手机验证功能

用户在客户端输入手机号,点击发送后随机生成4位数字码。有效期为90秒。

输入验证码,点击验证,返回成功或者失败。且每个手机号在一天内只能验证3次。并给相应信息提示

Redis 发布订阅

简介

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

示例

下图展示了频道 channel1 ,

以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

 

当有新消息通过 PUBLISH 命令发送给频道 channel1 时,这个消息就会被发送给订阅它的三个客户端:

 

命令

订阅频道:

SUBSCRIBE channel [channel ...]订阅给定的一个或多个频道的信息

PSUBSCRIBE pattern [pattern ...]订阅一个或多个符合给定模式的频道。

发布频道:

PUBLISH channel message 将信息发送到指定的频道。

退订频道:

UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。

PUNSUBSCRIBE [pattern [pattern ...]]退订所有给定模式的频道。

应用场景

这一功能最明显的用法就是构建实时消息系统,比如普通的即时聊天,群聊等功能

1在一个博客网站中,有100个粉丝订阅了你,当你发布新文章,就可以推送消息给粉丝们。

2微信公众号模式

Redis多数据库

Redis下,数据库是由一个整数索引标识,而不是由一个数据库名称。默认情况下,一个客户端连接到数据库0。

redis配置文件中下面的参数来控制数据库总数:

​ database 16 //(从0开始 1 2 3 …15)

 

select 数据库//数据库的切换

移动数据(将当前key移动另个库)

move key名称 数据库

数据库清空:

flushdb //清除当前数据库的所有key

flushall //清除整个Redis的数据库所有key

Redis事务

Redis 事务可以一次执行多个命令,(按顺序地串行化执行,执行中不会被其它命令插入,不许加塞)

简介

Redis 事务可以一次执行多个命令(允许在一次单独的步骤中执行一组命令), 并且带有以下两个重要的保证:

批量操作在发送 EXEC 命令前被放入队列缓存。

收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。

在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

1、Redis会将一个事务中的所有命令序列化,然后按顺序执行

2、执行中不会被其它命令插入,不许出现加赛行为

一个事务从开始到执行会经历以下三个阶段:

开始事务。

命令入队。

执行事务。

事务的错误处理:

队列中的某个命令出现了报告错误,执行时整个的所有队列都会被取消。

 

事务的错误处理:

如果执行的某个命令报出了错误,则只有报错的命令不会被执行,而其它的命令都会执行,不会回滚。

 

 

命令

 

Redis 不支持回滚(roll back)

正因为redis不支持回滚功能,才使得redis在事务上可以保持简洁和快速。

示例

示例1 MULTI EXEC

转帐功能,A向B帐号转帐50元

一个事务的例子,它先以 MULTI 开始一个事务,然后将多个命令入队到事务中,最后由 EXEC 命令触发事务

 

1输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行

2直到输入Exec后,Redis会将之前的命令队列中的命令依次执行

示例2 DISCARD放弃队列运行

 

1输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行

2直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

3命令队列的过程中可以通过discard来放弃队列运行

示例3事务的错误处理

事务的错误处理:

如果执行的某个命令报出了错误,则只有报错的命令不会被执行,而其它的命令都会执行,不会回滚。

 

 

示例4事务的错误处理

事务的错误处理:

队列中的某个命令出现了报告错误,执行时整个的所有队列都会被取消。

 

 

由于之前的错误,事务执行失败

示例5事务的WATCH

WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

需求:某一帐户在一事务内进行操作,在提交事务前,另一个进程对该帐户进行操作。

 

 

示例5 UNWATCH

Redis Unwatch 命令用于取消 WATCH 命令对所有 key 的监视。

如果在执行WATCH命令之后,EXEC命令或DISCARD命令先被执行的话,那就不需要再执行UNWATCH了

应用场景

一组命令必须同时都执行,或者都不执行。

我们想要保证一组命令在执行的过程之中不被其它命令插入。

商品秒杀(活动)。

Redis 脚本

Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。

Redis数据淘汰策略redis.conf

Redis官方给的警告,当内存不足时,Redis会根据配置的缓存策略淘汰部分Keys,以保证写入成功。当无淘汰策略时或没有找到适合淘汰的Key时,Redis直接返回out of memory错误。

最大缓存配置

在 redis 中,允许用户设置最大使用内存大小

​ maxmemory 512G

redis 提供6种数据淘汰策略:

  • volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰

  • volatile-lfu:从已设置过期的Keys中,删除一段时间内使用次数最少使用的

  • volatile-ttl:从已设置过期时间的数据集中挑选最近将要过期的数据淘汰

  • volatile-random:从已设置过期时间的数据集中随机选择数据淘汰

  • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰

  • allkeys-lfu:从所有Keys中,删除一段时间内使用次数最少使用的

  • allkeys-random:从数据集中随机选择数据淘汰

  • no-enviction(驱逐):禁止驱逐数据(不采用任何淘汰策略。默认即为此配置),针对写操作,返回错误信息

建议:了解了Redis的淘汰策略之后,在平时使用时应尽量主动设置/更新key的expire时间,主动剔除不活跃的旧数据,有助于提升查询性能

Redis持久化

简介

数据存放于:

内存:高效、断电(关机)内存数据会丢失

硬盘:读写速度慢于内存,断电数据不会丢失

RDB

 

RDB:是redis的默认持久化机制。 RDB相当于照快照,保存的是一种状态。

几十G数据--》几KB快照

快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

优点:

快照保存数据极快、还原数据极快

适用于灾难备份

缺点:

小内存机器不适合使用,RDB机制符合要求就会照快照

快照条件:

1、服务器正常关闭时 ./bin/redis-cli shutdown

 

2、key满足一定条件,会进行快照

​ vim redis.conf 搜索save

​ :/save

​ save 900 1 //每900秒(15分钟)至少1个key发生变化,产生快照

​ save 300 10 //每300秒(5分钟)至少10个key发生变化,产生快照

​ save 60 10000 //每60秒(1分钟)至少10000个key发生变化,产生快照

AOF

由于快照方式是在一定间隔时间做一次的,所以如果redis 意外down 掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof 持久化方式。

Append-only file:aof 比快照方式有更好的持久化性,是由于在使用aof 持久化方式时,redis 会将每一个收到的写命令都通过write 函数追加到文件中(默认是appendonly.aof)。当redis 重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

有三种方式如下(默认是:每秒 fsync 一次)

  • appendonly yes //启用 aof 持久化方式

  • # appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化

  • appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中

  • # appendfsync no //完全依赖 os,性能最好,持久化没保证

产生的问题:

aof 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用 incr test命令 100 次,文件中必须保存全部的 100 条命令,其实有 99 条都是多余的。

redis缓存与数据库一致性

解决方案

一、实时同步

对强一致要求比较高的,应采用实时同步方案,即查询缓存查询不到再从DB查询,保存到缓存;更新缓存时,先更新数据库,再将缓存的设置过期(建议不要去更新缓存内容,直接设置缓存过期)。

@Cacheable:查询时使用,注意Long类型需转换为Sting类型,否则会抛异常

@CachePut:更新时使用,使用此注解,一定会从DB上查询数据

@CacheEvict:删除时使用;

@Caching:组合用法

二、异步队列

对于并发程度较高的,可采用异步队列的方式同步,可采用kafka等消息中间件处理消息生产和消费。

 

三、使用阿里的同步工具canal

canal实现方式是模拟mysql slave和master的同步机制,监控DB bitlog的日志更新来触发缓存的更新,此种方法可以解放程序员双手,减少工作量,但在使用时有些局限性。

 

  1. master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events,可以通过show binlog events进行查看);

  2. slave将master的binary log events拷贝到它的中继日志(relay log);

  3. slave重做中继日志中的事件,将改变反映它自己的数据。

 

  1. canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议

  2. mysql master收到dump请求,开始推送binary log给slave(也就是canal)

  3. canal解析binary log对象(原始为byte流)

四、采用UDF自定义函数的方式

面对mysql的API进行编程,利用触发器进行缓存同步,但UDF主要是c/c++语言实现,学习成本高。

总结:

穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决办法: 持久层查询不到就缓存空结果,查询时先判断缓存中是否exists(key) ,如果有直接返回空,没有则查询后返回,

注意insert时需清除查询的key,否则即便DB中有值也查询不到(当然也可以设置空缓存的过期时间)

雪崩

雪崩:缓存大量失效的时候,引发大量查询数据库。解决办法:①用锁/分布式锁或者队列串行访问

​ ②缓存失效时间均匀分布

热点key

热点key:某个key访问非常频繁,当key失效的时候有大量线程来构建缓存,导致负载增加,系统崩溃。

解决办法:

①使用锁,单机用synchronized,lock等,分布式用分布式锁。

②缓存过期时间不设置,而是设置在key对应的value里。如果检测到存的时间超过过期时间则异步更新缓存。

③在value设置一个比过期时间t0小的过期时间值t1,当t1过期的时候,延长t1并做更新缓存操作。

4设置标签缓存,标签缓存设置过期时间,标签缓存过期后,需异步地更新实际缓存

 

Redis

4. 持久化
    1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
    2. redis持久化机制:
        1. RDB:默认方式,不需要进行配置,默认就使用这种机制
            * 在一定的间隔时间中,检测key的变化情况,然后持久化数据
            1. 编辑redis.windwos.conf文件
                #   after 900 sec (15 min) if at least 1 key changed
                save 900 1
                #   after 300 sec (5 min) if at least 10 keys changed
                save 300 10
                #   after 60 sec if at least 10000 keys changed
                save 60 10000
                
            2. 重新启动redis服务器,并指定配置文件名称
                D:\JavaWeb2018\day23_redis\资料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf  
            
        2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
            1. 编辑redis.windwos.conf文件
                appendonly no(关闭aof) --> appendonly yes (开启aof)
                
                # appendfsync always : 每一次操作都进行持久化
                appendfsync everysec : 每隔一秒进行一次持久化
                # appendfsync no     : 不进行持久化
​
5. Java客户端 Jedis
    * Jedis: 一款java操作redis数据库的工具.
    * 使用步骤:
        1. 下载jedis的jar包
        2. 使用
            //1. 获取连接
            Jedis jedis = new Jedis("localhost",6379);
            //2. 操作
            jedis.set("username","zhangsan");
            //3. 关闭连接
            jedis.close();
             Jedis操作各种redis中的数据结构
                1) 字符串类型 string
                    set
                    get
                //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
                //存储
                jedis.set("username","zhangsan");
                //获取
                String username = jedis.get("username");
                System.out.println(username);

            //可以使用setex()方法存储可以指定过期时间的 key value
            jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
    
            //3. 关闭连接
            jedis.close();
​
        2) 哈希类型 hash : map格式  
            hset
            hget
            hgetAll
            //1. 获取连接
            Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
            //2. 操作
            // 存储hash
            jedis.hset("user","name","lisi");
            jedis.hset("user","age","23");
            jedis.hset("user","gender","female");
    
            // 获取hash
            String name = jedis.hget("user", "name");
            System.out.println(name);

​ // 获取hash的所有map中的数据 Map<String, String> user = jedis.hgetAll("user"); // keyset Set<String> keySet = user.keySet(); for (String key : keySet) { //获取value String value = user.get(key); System.out.println(key + ":" + value); }

            //3. 关闭连接
            jedis.close();
​
​
        3) 列表类型 list : linkedlist格式。支持重复元素
            lpush / rpush
            lpop / rpop
            lrange start end : 范围获取
            
             //1. 获取连接
            Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
            //2. 操作
            // list 存储
            jedis.lpush("mylist","a","b","c");//从左边存
            jedis.rpush("mylist","a","b","c");//从右边存
    
            // list 范围获取
            List<String> mylist = jedis.lrange("mylist", 0, -1);
            System.out.println(mylist);
            
            // list 弹出
            String element1 = jedis.lpop("mylist");//c
            System.out.println(element1);
    
            String element2 = jedis.rpop("mylist");//c
            System.out.println(element2);
    
            // list 范围获取
            List<String> mylist2 = jedis.lrange("mylist", 0, -1);
            System.out.println(mylist2);
    
            //3. 关闭连接
            jedis.close();
​
​
        4) 集合类型 set  : 不允许重复元素
            sadd
            smembers:获取所有元素
​
            //1. 获取连接
            Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
            //2. 操作

​ ​ ​ // set 存储 jedis.sadd("myset","java","php","c++"); // set 获取 Set<String> myset = jedis.smembers("myset"); System.out.println(myset);

            //3. 关闭连接
            jedis.close();
        5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
            zadd
            zrange
​
            //1. 获取连接
            Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
            //2. 操作
            // sortedset 存储
            jedis.zadd("mysortedset",3,"亚瑟");
            jedis.zadd("mysortedset",30,"后裔");
            jedis.zadd("mysortedset",55,"孙悟空");
    
            // sortedset 获取
            Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
    
            System.out.println(mysortedset);

​ ​

​ //3. 关闭连接 jedis.close(); * jedis连接池: JedisPool * 使用: 1. 创建JedisPool连接池对象 2. 调用方法 getResource()方法获取Jedis连接 //0.创建一个配置对象 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(50); config.setMaxIdle(10); //1.创建Jedis连接池对象 JedisPool jedisPool = new JedisPool(config,"localhost",6379); //2.获取连接 Jedis jedis = jedisPool.getResource(); //3. 使用 jedis.set("hehe","heihei");

                    //4. 关闭 归还到连接池中
                    jedis.close();
        * 连接池工具类
            public class JedisPoolUtils {
​
                private static JedisPool jedisPool;
            
                static{
                    //读取配置文件
                    InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
                    //创建Properties对象
                    Properties pro = new Properties();
                    //关联文件
                    try {
                        pro.load(is);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //获取数据,设置到JedisPoolConfig中
                    JedisPoolConfig config = new JedisPoolConfig();
                    config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
                    config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
            
                    //初始化JedisPool
                    jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
                        }
​
                    /**
                     * 获取连接方法
                     */
                    public static Jedis getJedis(){
                        return jedisPool.getResource();
                    }
                }

 

案例:

案例需求:
    1. 提供index.html页面,页面中有一个省份 下拉列表
    2. 当 页面加载完成后 发送ajax请求,加载所有省份
​
​
* 注意:使用redis缓存一些不经常发生变化的数据。
    * 数据库的数据一旦发生改变,则需要更新缓存。
        * 数据库的表执行 增删改的相关操作,需要将redis缓存数据情况,再次存入
        * 在service对应的增删改方法中,将redis数据删除。

​ ​ ​以上笔记来自某位不知名的老师,感谢这位老师。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值