文章目录
redis
1. redis介绍
基本概念:
- redis是一款高性能的nosql(not only sql)系列的非关系型数据库
- not only sql,不仅仅是sql,这是一种新的数据库理念,泛指非关系型数据库
- 最开始是一个用来缓存服务器的,随着redis的发展才开始作为数据库来使用的。
缓存:
在计算机中可以用来存储数据的地方:数据库、硬盘、内存
- 数据库:数据可持久化、数据库的读写最慢
- 硬盘:数据可持久化、硬盘的读写较慢
- 内存:数据无法持久化、内存的读写最快、
- 缓存主要是为了提升用户的体验。比较常见的就是将数据库或者硬盘中的数据加载到内存中,然后只需要操作内存中的数据即可,需要定期将内存中的数据持久化到数据库或者硬盘即可。
常见的缓存服务器:
redis 、 memorycached
nosql产生的原因:
随着web2.0时代网站的兴起,传统的关系型数据库是无法满足web2.0时代大型网站的需求,特别是超大规模和高并发的网站,为了克服这个问题,选择非关系型数据库,因为非关系型数据库的特点能够满足超大规模和高并发的需求,所以redis得到了迅猛的发展。所以现在建立一个超大规模的网站,选择redis这种非关系型数据库是必须的。
nosql和关系型数据库的比较
-
优点:
1. 成本:nosql基本上都是开源的,关系型数据库比如oracle这种需要花费大量的成本去购买使用
2. 查询效率: nosql的数据存在于缓存中,关系型数据库是存在于硬盘中,nosql的查询效率更高
3. 存储方式:nosql主要以k-v方式或者文档方式,所以支持的数据类型更强大,可以直接存储:基本数据类型、对象、集合等。关系型数据库能够存储一些基本的数据类型
4. 扩展性:关系型数据库的扩展性更差一些 -
缺点:
新的技术,文档和维护的工具更少
不提供sql的支持,开发者需要花费更多的学习成本
不提供关系型数据库的事务管理 -
总结:
nosql和关系型数据库不是对立关系,而是互补的关系。一般情况下还是会继续使用关系型数据库,在需要使用nosql的时候,去添加nosql数据库,让nosql数据库针对关系型数据库的不足进行弥补,一般数据最终还是会存在于关系型数据库中,nosql数据库中会有一个备份 -
常见的nosql产品:
k-v形式: redis 优势:快速 劣势:存储的数据不是结构化的列存储模式: HBase 主要应用在大数据的环境下 ,优势:查询效率很高,可扩展性强 劣势:功能相对局限
文档型: mongdb 与k-v类似 v是结构化的数据 优势:数据结构要求不严格 劣势:查询效率相对较低
业务场景思考:秒杀
思考问题:缓存雪崩、缓存穿透、缓存击穿
2.redis的下载和安装
官网: https://redis.io
中文网站: https://www.redis.net.cn
下载后解压即可
解压以后有三个文件需要特别关注一下:
redis.windows.conf 配置文件
redis-server.exe 服务器文件
redis-cli.exe 客户端文件
启动redis服务器: redis-server.exe redis.windows.conf
启动客户端: redis-cli.exe (刚下的时候直接就可以启动)
[-h ip] 这个命令是输入你所要连接的主机ip,默认是本机
[-p port] 输入连接端口号
[-a password] 输入你的密码,刚下的时候是没有密码的
例子:redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456
主机ip:127.0.0.1
端口号:6379
密码:123456
密码也可以用命令 -a set来设置
3.redis配置文件介绍
文件名:redis.windows.conf
bind
172.16.12.200 绑定ip 客户端连接的时候使用的ip
port
6379 redis服务器绑定的端口
requirepass
123456 服务器的密码
timeout 0 超时时间 单位是s 当客户端连接超过指定的时间没有发送数据就自动断开 0表示不自动断开
loglevel notice
日志输出等级
具体等级
- debug (a lot of information, useful for development/testing)
- verbose (many rarely useful info, but not a mess like the debug level)
- notice (moderately verbose, what you want in production probably) 默认等级
- warning (only very important / critical messages are logged)
logfile ""
日志输出到哪里去 可以指定一个文件 可以是stdout 表示输出到控制台
databases 16
设置有多少个数据库 默认选中第0个 可以使用select 改变选中的数据库
保存数据到硬盘
save <seconds> <changes>
save 900 1
save 300 10
save 60 10000
rdbcompression yes
在保存数据的时候是否需要压缩这个数据 默认采用LZF压缩算法 如果需要节省保存时间可以考虑关闭这个功能 但是会导致保存后的数据很大 如果不压缩,yes换成no即可
dbfilename dump.rdb
** 保存数据的文件名**
dir ./
保存目录 ./ 这个表示当前目录 同时也可以自己修改保存路径
maxclients 10000
同一时间的最大连接数,最大可以连接的客户端数
maxmemory <bytes>
最大内存限制 单位是字节 redis在的启动的时候会将硬盘中的数据加载到内存中,如果已经达到最大限制,则redis会尝试清除已经到期或者即将到期的数据,如果还是达到最大限制,则无法进行写入操作,但是还是可以进行读取操作
appendonly no
添加数据的时候是否需要记录日志
appendfilename "appendonly.aof"
写的日志(就是上面是否记录哪个日志)保存的文件
更新数据的条件
appendfsync always
每次更新数据都会写入硬盘 (慢)
appendfsync everysec
每一秒写一次数据到硬盘
appendfsync no
等redis自动将数据写入硬盘,也就是上面的save哪个配置时间
4. redis的集群配置
redis的集群配置主要是主从配置:一主多从 主服务器可以修改数据 从属服务器只能查询数据
- 设置主服务器
可以随便选取一个redis作为主服务器,这里我选定我F:\reids\redis-4.014
这个路径下的服务器为主服务器
- 配置从服务器
2.1 在我的D:\redis
路径下创建两个从服务器
2.2 打开这两个服务器的配置文件进行服务器配置
配置以下几个字段
slaveof <masterip> <masterport>
配置当前服务器为从属服务器 注意:主服务器需要绑定ip 这里输入主服务器的ip和端口
masterauth <master-password>
连接主服务器需要的密码
slave-read-only yes
从属服务器只能查询数据
配置好了后就可以启动一下主从服务器看是否成功
在主服务器的客户端去设置数据
在从服务器的客户端去查看主服务器的数据,就可以验证是否连接成功
注意:在这里要记得去连接从服务器的端口号,代表运行的是从服务器的
5. 哨兵模式
哨兵模式的解释:
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。就是当服务器崩掉的时候,客户端是不知道服务器崩掉了的,那这样客户端去进行操作也操作不了,所以这时就会在创建哨兵来监听服务器,哨兵的工作就是,在一定时间内去监听服务器是否正常工作,如果发现服务器崩掉了就会去告诉客户端,这样客户端就知道自己所连接的服务器崩掉了;一般哨兵至少需要3个,当有2个哨兵都告诉客户端服务器崩掉后,这样的消息才是可信的。
哨兵模式的配置:
- 将服务器调整为一主多从(6379带6380、6381)。
- 在/usr/local/myredis文件夹下创建sentinel.conf文件(名字一定不能错)。
- 配置哨兵,sentinel.conf添加内容
sentinel monitor myredis 127.0.0.1 6379 1
- 其中:myredis 为监控对象起的服务器名称(随意),1代表至少有1个哨兵投票同意迁移
- 如果Master存在密码,需要配置sentinel auth-pass 服务器名 密码
sentinel auth-pass myredis 123456 - 启动哨兵,在/usr/local/bin/文件夹下执行./redis-sentinel /usr/local/myredis/sentinel.conf命
令。
复制延迟
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有
一定的延迟,Slave机器数量的增加,会使延迟问题会更加严重
6. 数据类型
在redis中常见的数据类型有:
string字符串、set集合、list列表、hash、zset有序集合
在redis中所有的数据都是以k-v的方式进行存储的
6.1. string字符串常见命令:
set key value [EX seconds] [PX millseconds] 将字符串存入redis key 是数据的键 value 是数据的值 **EX是设置过期时间单位是秒** **PX是设置过期时间单位是毫秒**
set aa bb EX 10
get key 获取指定key的值
get aa
getrange key start end 获取指定key的值的指定范围的字符串,前后都是闭区间
getrange aaa 1 3
getset key value 修改指定的值返回旧的值
getset aaa 654321
setex key seconds value 和 set key value [EX seconds] 效果是一样的 可以设置过期时间
psetex key millseconds value 和 set key value [PX millseconds] 效果是一样的
del key [key...] 删除指定的key
6.2. set集合常见命令
无须不重复的值
sadd key member [member...] 往集合中添加一个或多个值
sadd myset a b c d
smembers key 获取集合中的所有元素
smembers myset
srem key member [member...] 删除指定key中的一个或多个值
srem myset a d
scard key 获取集合中元素的个数
6.3 list列表
有序看了重复的
添加
lpush key value [value...] 往列表的左边添加数据,相当于就是从头部开始添加
rpush key value [value...] 往列表的右边添加数据,相当于从尾部开始添加
获取
lrange key start end 获取列表中指定范围内的数据
lrange mylist 0 -1 获取全部数据
lindex key index 获取列表中指定位置的数据
lindex mylist 1
llen key 获取列表的长度
llen mylist
删除
lpop key 删除并返回第一个元素
rpop key 删除并返回最后一个元素
修改
lset key index value 修改指定列表的指定位置上的数据
6.4 zset集合
zset集合是有序不重复的,有序的意思是按照给的分数来的
在添加数据的时候会给每一个元素添加一个double类型的分数(score) ,通过这个分数进行排序,元素不能重复,分数可以重复
添加
zadd key score value [score value...] 添加一个或多个元素 需要指定分数
zadd myzset 1 a 2 b 3 c 4 d
获取
zrange key start end [withscores] 获取指定范围内的数据 withscores 表示查询的结果是否带上分数
zrange myzset 0 2
zcard key 获取集合中的元素个数
zrank key member 获取集合中指定元素的位置 zrank myzset a
zscore key member 获取指定元素的分数
删除
zrem key member 删除集合中的指定元素
6.5 hash 哈希
hash是一个string类型的k-v映射表 比较适合存放对象的
添加和修改
hset key field value 将hash中的field的值设置成value
hmset key field value [field value...] 同时设置多个值进去
获取
hget key field 获取hash中指定field的值
hgetall key 获取hash中所有的字段和值
hexists key field 判断hash中是否存在field
hlen key 获取hash中的个数
hkeys key 获取hash中所有的key
hmget key field [field...] 获取指定的字段的值
删除
hdel key field [field...] 删除hash指定的field
注意:存进去的一定是按照k-v形式的,按照个数就是,奇数位就是它的k值,偶数位上的就是它的v值
6.6 通用命令
keys * 查看所有的键
type key 查看指定key的数据类型
del key 删除指定的key
config get name 获取配置文件中的配置信息
7. jedis
对于我们来说主要还是需要使用java来操作redis,jedis是一款java操作redis的客户端工具
添加依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
jedis简单演示:
import redis.clients.jedis.Jedis;
public class JedisTest {
public static void main(String[] args) {
string();
}
public static void string(){
//创建客户端用户连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
// Jedis jedis = new Jedis("localhost", 6379); //在这里,localhost会去转换成本地的bind值,也就是127.0.0.1
// Jedis jedis = new Jedis("本地指定ip", 6379); //如果直接放本地设置的指定的ip的话是不可以的,因为不会自动转换,除非把redis配置文件中的bind值给注释掉
//认证,也就是输入密码
//jedis.auth("");
String aa = jedis.get("aa");
System.out.println(aa);
jedis.close();
}
}
注意:
创建客户端对象的适合,ip要填配置文件中bind一样的才可以,如果想要任意一个客户端都能连接,可以将bind给注释掉,或者想要指定的可以连接那就使用设置多个bind去完成
7.1 jedis操作
其实jedis里面都有包含了所有命令的方法,要使用哪一个方法,直接使用jedis去调用即可,部分数据类型演示,其实都很类似:
- 创建客户端连接对象
- 认证
- 进行操作(每一种命令都有对于封装好了的方法)
- 关闭
import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class JedisTest {
public static void main(String[] args) {
//string();
// list();
set();
}
public static void string(){
//创建客户端用户连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
// Jedis jedis = new Jedis("localhost", 6379); //在这里,localhost会去转换成本地的bind值,也就是127.0.0.1
// Jedis jedis = new Jedis("本地指定ip", 6379); //如果直接放本地设置的指定的ip的话是不可以的,因为不会自动转换,除非把redis配置文件中的bind值给注释掉
//认证,也就是输入密码
//jedis.auth("");
jedis.select(0);//设置选中的数据库 默认是0
String aa = jedis.get("aa");//获取字符串类型的值
System.out.println(aa);
String uuid = jedis.set("uuid", UUID.randomUUID().toString());
System.out.println(uuid);
jedis.close();
}
public static void list(){
//创建客户端用户连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
//认证,也就是输入密码
//jedis.auth("");
jedis.lpush("mylist","a","b","c");
List<String> mylist = jedis.lrange("mylist", 0, -1);
System.out.println(mylist);
jedis.close();
}
public static void set(){
//创建客户端用户连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
//认证,也就是输入密码
//jedis.auth("");
jedis.sadd("myset","a","b","c");
Set<String> myset = jedis.smembers("myset");
System.out.println(myset);
jedis.close();
}
}
7.2 jedis连接池
public static void pool(){
//创建连接池的配置对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//这里就可以去设置连接池的熟悉了,比如连接最大数、超时时间等
jedisPoolConfig.setMaxTotal(10);
//通过配置对象去创建连接池对象(注意这个连接池对象是没有认证方法的,所以如果有密码的话,要在创建连接池对象的时候添加进去)
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379,2000,"");
//从连接池获取连接
Jedis resource = jedisPool.getResource();
//使用连接对象去进行相关的操作即可
String s = resource.get("myset");
System.out.println(s);
resource.close();
}
注意:创建连接池对象的时候:连接池对象是没有认证方法的,所以如果有密码的话,要在创建连接池对象的时候添加进去)