《数据库学习》Redis数据库系统学习

本文详细介绍Redis数据库的搭建、使用、数据类型及其应用场景,包括键操作、事务处理、脚本编写、性能测试等内容,适合初学者快速掌握Redis的基础与进阶知识。

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

本文主要学习Redis数据库的搭建和使用。

一、Redis 介绍

    Redis 简介
       Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
       Redis 与其他 key - value 缓存产品有以下三个特点:
       Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
       Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
       Redis支持数据的备份,即master-slave模式的数据备份。
    Redis 优势
       性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
       丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
       原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
       丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
    Redis与其他key-value存储有什么不同?
       Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
       Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问

二、使用场景

  • 取最新N个数据的操作
  • 排行榜,取top N个数据 // 最佳人气前10条
  • 精确的设置过期时间
  • 计数据
  • 实时系统,反垃圾系统
  • pub , sub构建实时消息系统
  • 构建消息队列
  • 缓存

三、Windos环境安装

  1. Window 下安装(64位的,如果要32位请到网上提供的云盘地址下载。)
    下载地址:https://github.com/tporadowski/redis/releases
    然后将64位压缩包安装到本地,然后解压即可.
    在这里插入图片描述

四、Redis使用

1.将redis的安装路径配置在环境变量中,方便后续使用
2.打开环境变量配置。
在这里插入图片描述
3.在系统变量中找到path,然后编辑。
在这里插入图片描述
4. 将redis路径配置进去,然后保存即可。
在这里插入图片描述
5. 启动服务端。

  1. 用cmd命令,打开一个dos命令窗口,输入命令redis-server -v ,查看redis是否安装成功,如果成功,则会显示版本信息。
    在这里插入图片描述2. 然后输入命令 redis-server.exe 来启动redis。(弹出防火墙的话,点击允许就好)
    在这里插入图片描述3. 这样redis就启动成功了。其中
    Redis 3.2.100 (00000000/0) 64 bit 表示 Redis的版本是3.2.100 运行在64位操作系统中
    Port 6379 代表Redis为我们提供的默认端口
    PID 代表该Redis的进程pid。

6.启动客户端

  1. 然后我们重新打开一个dos命令窗口,输入命令redis-cli.exe -h 127.0.0.1 -p 6379 来启动客服端(127.0.0.1代表本地ip,6379 代表上述服务端的端口号。), 这样我们就可以和服务端进行通信。
    在这里插入图片描述
  1. 尝试操作redis数据库

服务端可客户端我们都已经启动成功,接下来,我们在客户端中往数据库中添加数据

  1. 我们输入set 程序会自动弹出如下内容。
    在这里插入图片描述
    2.我们在set后面输入 key的值(nam),在key后面输入value的值 tomatocc,然后回车
    在这里插入图片描述
    3.这样我们就将数据放进去了。
    4.接下来我们通过key的值来获取这条数据,输入get nam ,然后回车,这样我们就完成了redis数据库的基本操作。
    在这里插入图片描述

五、Redis的配置说明

  1. 关于redis的配置文件中的参数(推荐),可以参考:https://www.cnblogs.com/wudequn/p/8059412.html , 这种方式是通过修改配置文件的方式拉修改redis的配置。(只需要修改redis.windows.conf文件就好,该文件时客户端的配置)

  2. 通过命令的方式修改配置参数(该方法直再当前窗口中有效,重启后无效)。

  1. 输入命令 config get loglevel 来查看当前的日志输出级别。
    在这里插入图片描述
    2.输入命令config set loglevel debug 设置当前redis的日志输出级别是debug。
    在这里插入图片描述

更多的详细命令请参考: http://www.runoob.com/redis/redis-conf.html
备注: daemonize 设置为yes表示可以后台运行

注意:因为我对redis设置了环境变量,因此每次启动的时候不需要在cmd中切换到redis的安装目录中,但是这也存在一个问题,就是我修改redis的安装目录下的redis.windows.conf配置文件后,每次通过redis-server.exe启动后,配置文件根本不会生效。找了很多办法才发现,这是因为启动后的redis加载的不是redis安装目录下的配置文件,因此需要在启动的使用用如下格式命令C:\Users\55386>redis-server.exe d:\Redis\redis.windows.conf,去定位到你所需要的配置文件才可以

六、Redis 数据类型

 - Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)- String 类型
       - string 是redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
       - string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
       - string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

示例代码
在这里插入图片描述

  • Hash(哈希)
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

// hset 一次设置一个值,hget 一次得到一个值
示例代码(严格区分大小写)
在这里插入图片描述
// hmset 一次设置多个值,hgetall一次可以去除多个值
示例代码
在这里插入图片描述
当然,也可以一个个取值,如下图
在这里插入图片描述

  • List(列表)
  Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 

示例代码 :
1.存值
在这里插入图片描述
2.取值 lrange key start stop
在这里插入图片描述
3. 也可以同时存多个值
在这里插入图片描述
在这里插入图片描述

  • Set(集合)
       - Redis的Set是string类型的无序集合,并且是无重复的。
       - 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)

示例代码
// 添加数据,(我们可以看到我们实际添加了6组数据,但是其中有重复,所以最终只添加进去了5组)
在这里插入图片描述
// 查询数据
在这里插入图片描述

  • zset(sorted set:有序集合)
 Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
 - zset的成员是唯一的,但分数(score)却可以重复。

示例代码
存值,创建一个source的zset,存放学生和分数。
在这里插入图片描述
取值,取source这个zset,按照从0-100分(最大到最小)来显示
在这里插入图片描述
在这里插入图片描述
当然也可以用西面这种方式同时显示key和value。
在这里插入图片描述

五种数据类型的应用场景总结:

在这里插入图片描述

七、Redis数据库的键操作

    127.0.0.1:6379> flushdb` #清空当前数据库
  1. Redis数据库是针对key来操作的,下面来操作几个常用的关于key的操作

127.0.0.1:6379> set name "123" # 插入一个key是name,value 是 123的数据
127.0.0.1:6379> del name # 删除一个key的名字是name的数据
127.0.0.1:6379> exists name # 判断一个key的名字是 name 的数据是否存在
127.0.0.1:6379> expire name seconds #给这个名字是name的key设置过期时间,单位是秒(过期之后,该key就不存在)
127.0.0.1:6379> pexpire name milliseconds #给这个名字是name的key设置过期时间,单位是毫秒(过期之后,该key就不存在)
127.0.0.1:6379> persist name #删除名字是name的key的过期时间。
127.0.0.1:6379> keys pattern # 查询pattern(正则表达式)所匹配的所有key。
127.0.0.1:6379> keys name* # 查询所有以name开头的key。
127.0.0.1:6379> move name 1 # 将名字是name的key移动到数据库1中(注意:如果目标库中又同名的key,则不能移动)
在这里插入图片描述
127.0.0.1:6379> flushdb # 清空当前数据库
127.0.0.1:6379> randomkey #使用该命令可以从但前数据库中随机返回一个key
127.0.0.1:6379> type name # 查看名字是name的key所对应的数据类型。

  1. Redis字符串操作

127.0.0.1:6379> getrange name 0 5 #表示获取名为name的key的value,并从0开始截取,截取长度为5.
在这里插入图片描述
127.0.0.1:6379> getrange name 2 -1 #表示获取名为name的key的value,并从2开始截取,截取到末尾.
在这里插入图片描述
127.0.0.1:6379> getset name "this is new demo" # 给名字是name的key重新赋值(会返回原来的值)
在这里插入图片描述
127.0.0.1:6379> mget name name1 # 同时获取name 和name2这两个key的value。
在这里插入图片描述
127.0.0.1:6379> strlen name 获取名字是name的key所对应value的长度。
在这里插入图片描述
127.0.0.1:6379> incr count # 将名称是count的存储的数字增加1
127.0.0.1:6379> incrby count 10 # 将名称是count的存储的数字增加10
在这里插入图片描述
127.0.0.1:6379> decr count # 将名称是count的存储的数字减去1
127.0.0.1:6379> decrby count 10 # 将名称是count的存储的数字减去10
在这里插入图片描述
127.0.0.1:6379> append key value # 将指定value追加到另一个key的末尾
在这里插入图片描述

  1. Redis哈希操作

127.0.0.1:6379> hgetall userinofo #获取名字是userinofo哈希中所有的字段及相对应的值
127.0.0.1:6379> hdel userinofo password school #删除名字是userinofo哈希中字段名是password和school两条数据。
127.0.0.1:6379> hexists userinofo username # 判断userinofo哈希中是否存在username这个字段,如果存在会显示1,否则为0
127.0.0.1:6379> hget userinofo username # 获取userinofo哈希中字段是username的value值。
127.0.0.1:6379> hincrby userinofo age 10 # 向userinofo哈希中新增一个字段是age,value是10的数据
127.0.0.1:6379> hkeys userinofo # 获取userinofo哈希中的所有的字段名。
127.0.0.1:6379> hlen userinofo # 获得userinofo哈希中所有字段的个数
127.0.0.1:6379> hmget userinofo age username # 获取userinofo哈希中age字段和username字段所对应的value(字段可以是多个)
127.0.0.1:6379> hget userinofo age # 获取userinofo哈希中age字段所对应的value(字段只能是一个)
127.0.0.1:6379> hset userin user "toma" # 设置一个哈希是userin的数据,后面跟字段和value
127.0.0.1:6379> hget userin user # 获得userin哈希中字段是user的value。
127.0.0.1:6379> hvals userinofo # 获得userinofo哈希中所有的value。

  1. Redis列表操作

lpush和rpush的区别(正序和倒序)
127.0.0.1:6379> lpush mylist a b c d
(integer) 4
127.0.0.1:6379> rpush rpush a b c d
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1 // lrange 是查看列表中的数据(0 -1是查看所有)
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> lrange rpush 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
//////////////////////////////////////////////////////////////////////////////
127.0.0.1:6379> lpop mylist # 从mylist列表第一个位置移除一个元素
127.0.0.1:6379> llen mylist # 获取mylist列表长度
127.0.0.1:6379> lindex mylist 0 # 获取mylsit 列表第0个位置元素
/////////////////////////////////////////////////////////////////////////////
127.0.0.1:6379> lpush testkey a b c a a a a d #创建一个testkey的列表
(integer) 8
127.0.0.1:6379> lrem testkey 3 a #在testkey列表中移除3(count)个value是a的元素
(integer) 3
127.0.0.1:6379> lset testkey 1 "thistest" # 向testkey列表中的第1个位置插入数据
127.0.0.1:6379> ltrim testkey 1 2 #对testkey列表进行剪切,剪切位置是1到2。
127.0.0.1:6379> rpushx testkey7 # 向testkey列表中添加7这个值

5.Redis对Set集合操作

元素没有顺序,不重复
127.0.0.1:6379> smembers myset #获得myset的set集合的数据。
127.0.0.1:6379> scard myset #获得myset的set集合的成员数(长度)。
127.0.0.1:6379> sdiff myset you # 获得myset 和you这两个set集合的差集。
127.0.0.1:6379> sdiffstore newset myset you #将myset和you这两个set集合的差集放到一个新的newset集合中。
127.0.0.1:6379> sinter myset you # 获得myset和you这两个set集合的交集。
127.0.0.1:6379> sinterstore pubset myset you # 将myset和you这两个set集合的交集放到一个新的pubset集合中。
127.0.0.1:6379> sismember myset fish #判断myset集合中是否有fish这个元素,返回0,则没有
(integer) 0
127.0.0.1:6379> smove you myset cat' # 将you集合中的cat元素移动到myset集合中。
在这里插入图片描述
127.0.0.1:6379> spop myset #随机从myset集合中移除一个元素。
127.0.0.1:6379> spop myset 5 #随机从myset集合中移除5个元素。
127.0.0.1:6379> srandmember you 3 #随机从you集合中获取3个元素。
127.0.0.1:6379> srem you a dog #移除you集合中的a元素和dog元素
127.0.0.1:6379> sunion pubset newset you # 获取pubset和newset和you这三个集合的并集(结果会去重)
127.0.0.1:6379> sunionstore unset pubset newset you #将pubset和newset和you这三个集合的并集(结果会去重),重新放入到一个unset集合中。

6.Redis对ZSet集合操作

zset和set有一个共同点,就是没有重复,但是不一样的是,zset是有序的。

127.0.0.1:6379> zadd seazon 1 chun # 向seazon这个zset集合中添加一个分数是1的chun元素。
127.0.0.1:6379> zrange seazon 0 -1 # 获取seazon这个zset集合的所有元素(0 -1表示所有)(分数从低到高
127.0.0.1:6379> zrange seazon 0 -1 withscores # 获取seazon这个zset集合的所有元素(0 -1表示所有,也代表索引),并将分数也显示出来(分数从低到高
127.0.0.1:6379> zrevrange seazon 0 -1 # 获取seazon这个zset集合的所有元素(0 -1表示所有,也代表索引)(分数从高到低
127.0.0.1:6379> zrevrange seazon 0 -1 withscores# 获取seazon这个zset集合的所有元素(0 -1表示所有,也代表索引),并将分数也显示出来(分数从高到低
127.0.0.1:6379> zrevrange seazon 0 1 #获取seazon集合中分数最高的前两个元素(0和1是索引值)
127.0.0.1:6379> zcard seazon #获得seazon这个zset集合的成员数(个数)
127.0.0.1:6379> zcount seazon 2 3 # 计算分数在2到3之间元素的个数
127.0.0.1:6379> zincrby seazon 10 qiu # 对seazon集合中的qiu元素的分数增加10(如果该集合中不存在qiu这个元素,则会将qiu这个元素新增到seazon集合中,分数为10)
127.0.0.1:6379> zscore seazon qiu #获取seazon集合中qiu这个元素的分数
127.0.0.1:6379> zrem seazon qiu #从seazon集合中移除qiu这个元素
127.0.0.1:6379> zrank seazon dong # 获取seazon集合中dong这个元素的索引值

7.Redis对 HyperLogLog(基数估算)的操作

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。
127.0.0.1:6379> pfadd pdm a b c d a b c d e #向pdm中增加9个元素
127.0.0.1:6379> pfcount pdm # 计算pdm的基数为5(元素去重后的个数)
(integer) 5

将两个集合合并后统计基数
在这里插入图片描述

  1. Redis的订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
在这里插入图片描述
详细教程demo,参见:Redis的订阅服务使用

9.Redis中的事务

redis事务可以一次性执行多条命令
1)事务是一个单独的隔离操作:事务中所有的命令都会序列化,按顺序执行,执行过程中,不会被其他的客户端发送的命令打断
2)事务是一个原子操作,事务中的命令,要么全部完成,要么一个也不执行。
一个事务从开始执行到完成,要有以下三个阶段
开始事务
执行命令
提交事务
127.0.0.1:6379> multi # 开启一个事务
OK
127.0.0.1:6379> sadd myset a b c #在这个事务中创建一个myset的set
QUEUED #表示在排队等待中
127.0.0.1:6379> lpush mylist aa dd#在这个事务中创建一个mylist 的list
QUEUED
127.0.0.1:6379> smembers myset#在这个事务中显示myset的所有元素
QUEUED
127.0.0.1:6379> exec # 执行这个事务
1) (integer) 1
2) (integer) 5
3)
1) "v"
2) "c"
3) "a"
4) "b"

10.Redis的脚本

Lua脚本的功能是将redis命令打包为一个Lua脚本,在服务器端原子执行。和redis的事务特性相比,减少了网路开销,一次提交打包的命令;原子性执行避免出现watch的竞态条件;同时可以被复用,存储之后继续使用
在脚本中调用redis命令
call pcall – redis.call (‘get’,key) ,自动将Redis的数据类型转为lua数据类型
在这里插入图片描述
两者的区别在于call如果执行失败,停止运行,并且返回一个脚本错误,pcall如果执行错误,会记录错误,并继续执行。
从脚本中返回值
在脚本中使用return将脚本的执行结果返回给客户端,如果没有执行return语句默认返回nil,在此过程中也会自动将lua类型转为redis数据类型

执行格式: EVAL 脚本内容 key参数的数量 [key…] [arg…]

    127.0.0.1:6379> eval "return redis.call('set',KEYS[1],argv[1]) "  1 testkey helllo
    (error) ERR Error running script (call to f_343f7a0a3fa477a07fc40f89182ac25947302d24): @enable_strict_lua:15: user_script:1: Script attempted to access unexisting global variable 'argv'
    127.0.0.1:6379>  eval "return {ARGV[1]+ARGV[2]}" 2 key1 ksy2 13 5
      1) (integer) 18

注意到,KEYS ,ARGV这两个全局变量是需要大写的,(Lua语言是区别大小写的),写Lua脚本的时候需要注意
当脚本不需要任何参数的时候,不能省略这个参数(keynumber需要设置为0)

11.Redis的连接

127.0.0.1:6379> auth "admin" #验证当前redis的密码是否为admin(可以用命令
config get requirepass来查看密码)
127.0.0.1:6379> echo "tomatocc demo" # 打印指定字符串(tomatocc demo)
127.0.0.1:6379> quit #关闭当前连接
127.0.0.1:6379> PING #查看当前服务是否可用
127.0.0.1:6379> select index #切换到指定数据库

12.Redis服务器

127.0.0.1:6379> client list # 获取连接到服务器的所有客户端连接列表
127.0.0.1:6379> client setname tomatocc # 设置当前连接的名称
127.0.0.1:6379> client getname # 获取当前连接的名称
127.0.0.1:6379> client kill 127.0.0.1:56441 #关闭ip是127.0.0.1端口为56441的客户端连接
127.0.0.1:6379> client kill ID 4 #关闭链接ID是4的客户端链接
127.0.0.1:6379> config rewrite # 把配置直接写到配置文件中
127.0.0.1:6379> command #获取Redis命令详细数组
127.0.0.1:6379> command count #获取Redis命令总数
127.0.0.1:6379> time # 返回当前服务器时间
1) "1544685203" #当前时间(以 UNIX 时间戳格式表示)
2) "93603" #当前这一秒钟已经逝去的微秒数
127.0.0.1:6379> dbsize #或缺当前数据库所有key 的数量
127.0.0.1:6379> debug object myset #查看key是myset的内部信息
在这里插入图片描述
127.0.0.1:6379> debug segfault # 使Redis服务崩溃
127.0.0.1:6379> flushall # 删除所有数据库的所有key
127.0.0.1:6379[1]> flushdb #删除当前数据库中所有key
127.0.0.1:6379> info #获取 Redis 服务器的各种信息和统计数值
127.0.0.1:6379> info cpu #获取 Redis 服务器cpu的信息
127.0.0.1:6379> lastsave #返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示
127.0.0.1:6379> monitor #实时打印出Redis服务器接收到的命令(配合调式)
在这里插入图片描述
127.0.0.1:6379> role # 返回主从实例所属的角色
127.0.0.1:6379> save #同步保存数据到硬盘
Redis设置主从 参考教程 : Redis设置主从数据库

八、Redis高级教程

1.数据备份和恢复

127.0.0.1:6379> save #该命令将在 redis 安装目录中创建dump.rdb文件,并将数据存储在里面
恢复数据: 如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。

2.性能测试

C:\Users\55386> redis-benchmark -h # 查看性能测试的基准参数
C:\Users\55386>redis-benchmark -q -n 100000 #每秒执行 100000个请求的性能。
C:\Users\55386>redis-benchmark -t set,lpush -q -n 1000 #每秒执行1000 个set和lpush的性能。
在这里插入图片描述

3.Redis的管道技术

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
服务端处理命令,并将结果返回给客户端。
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

4.Java链接Redis

首先引入Redis所需要的jar包,这里自己百度下载就好。下面展示示例代码。

package tomatocc;

import redis.clients.jedis.Jedis;

/***
@author tomatocc
@desc Redis数据库测试
*/

public class RedisTest {
	public static void main(String[] args) {
		//连接Redis   设置ip和端口
		Jedis redis = new Jedis("127.0.0.1",6379);
		System.out.println("redis connect success .");
		// 设置Redis链接密码
		redis.auth("admin");
		//查看服务是否运行
		System.out.println("服务正在运行: "+redis.ping());// PONG 表示正确
		// 关闭链接
		redis.close();
	}

}
	public static void main(String[] args) {
		//连接 Redis   设置ip和端口
		Jedis redis = new Jedis("127.0.0.1",6379);
		System.out.println("redis connect success .");
		// 设置密码
		redis.auth("admin");
		/**对String类型进行操作*/
		// 创建一个字符串myset
		redis.set("myset", "张三");
		// 追加字符
		redis.append("myset", "是个学生");
		// 输出这个字符串
		System.out.println(redis.get("myset"));
		// 同时设置多个String
		redis.mset("name", "小强","password","123" ,"note","备注");
		// 输出这些set
		System.out.println(redis.get("name") + "," + redis.get("password") + "," + redis.get("note") + ".");
		// 创建一个age的字符串
		redis.set("age", "10");
		System.out.println(redis.get("age"));
		//将age 增加1
		redis.incr("age");
		System.out.println(redis.get("age"));
		
		// 关闭链接
		redis.close();
	}

在这里插入图片描述

// 然后设置dos窗口的编码格式
-首先输入命令 :chcp 65001 设置dos窗口编码为utf-8
-然后设置字体:右键--->属性
在这里插入图片描述
然后登陆数据库:
C:\Users\55386>redis-cli.exe -h 127.0.0.1 -p 6379 --raw
然后在获取值,这样中文就不会乱码。
在这里插入图片描述

5.Java使用Redis之连接池

首先我们导入jar ---->   commons-pool2-2.6.0.jar
然后创建Redis连接池的工具类
package kit;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/***
@author xinleiwu
@desc Redis的工具类
*/

public class RedisKit {
	private RedisKit() {}
	
	private static String ip = "127.0.0.1";
	private static int port = 6379;
	private static int timeout = 10000;
	private static String auth = "admin";
	
	private static JedisPool pool  = null ;
	static {
		/***初始化连接池*/
		JedisPoolConfig config = new JedisPoolConfig();
		// 设置最大链接数
		config.setMaxTotal(1024);
		// 设置最大空闲实例数
		config.setMaxIdle(200);
		// 设置连接池最大等待时间, 毫秒(如果是-1 表示永不超时,会一直等)
		config.setMaxWaitMillis(10000);
		// borrow一个实例的时候,是否提前进行validate操作
		config.setTestOnBorrow(true);
		
		// 创建链接池                      
		pool = new JedisPool(config,ip,port,timeout,auth);
	}
	
	// 得到Redis链接 (同步的)
	public synchronized static Jedis getJedis() {
		if(pool != null) {
			return pool.getResource(); // 获取链接
		}
		return null;
	}
	
	// 关闭redis链接
	public static void close (final Jedis redis) {
		if(redis != null) {
			redis.close();
		}
	}
}

然后将之前的代码进行改造,输出结果完全一致

	public static void main(String[] args) {
/*		//连接 Redis   设置ip和端口
		Jedis redis = new Jedis("127.0.0.1",6379);
		System.out.println("redis connect success .");
		// 设置密码
		redis.auth("admin");*/
		Jedis redis = RedisKit.getJedis();
		/**对String类型进行操作*/
		// 创建一个字符串myset
		redis.set("myset", "张三");
		// 追加字符串
		redis.append("myset", "是个学生");
		// 输出这个字符串
		System.out.println(redis.get("myset"));
		
		// 同时设置多个String
		redis.mset("name", "小强","password","123" ,"note","备注");
		// 输出这些字符串
		System.out.println(redis.get("name") + "," + redis.get("password") + "," + redis.get("note") + ".");
	
		// 创建一个age的字符串
		redis.set("age", "10");
		System.out.println(redis.get("age"));
		//将age 增加1
		redis.incr("age");
		System.out.println(redis.get("age"));
		// 关闭链接
		RedisKit.close(redis);
	}
	/**
	 * 排序
	 */
	static void testSort() {
		Jedis redis = RedisKit.getJedis();
		redis.del("a");// 删除key
		redis.lpush("a", "aa");
		redis.lpush("a", "xx");
		redis.lpush("a", "ee");
		redis.lpush("a", "dd");
		redis.lpush("a", "rr");
		
		System.out.println(redis.lrange("a", 0, -1 ));
		//降序
		System.out.println(redis.sort("a",new SortingParams().alpha().desc()));
		//升序
		System.out.println(redis.sort("a",new SortingParams().alpha().asc()));
		RedisKit.close(redis);
	}

延伸阅读

Redis配置数据持久化—appendonly
Redis基本类型以及优点特性

redis的过期策略以及内存淘汰机制

分析:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来。比如你redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的,这个问题思考过么?还有,你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么?
回答:
redis采用的是定期删除+惰性删除策略。
为什么不用定时删除策略?
定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.
定期删除+惰性删除是如何工作的呢?
定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。
于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。
采用定期删除+惰性删除就没其他问题了么?
不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。
在redis.conf中有一行配置

maxmemory-policy volatile-lru

该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己)
1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。
2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。
3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。
4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐
ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

欢迎关注本人个人公众号,交流更多技术信息

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tomatocc

赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值