浅谈Redis数据库

发布于:2023-01-05 ⋅ 阅读:(266) ⋅ 点赞:(0)

一、NoSQL与Redis

NoSQL 是 Not Only SQL 的缩写,意思是“不仅仅是SQL”的意思,泛指非关系性数据库。强调Key-Value Stores和文档数据库的优点。

NoSQL产品是传统关系型数据库的功能阉割版本,通过减少用不到或很少用的功能,来大幅度提高产品性能(性能为王)

我们使用:Java、set等语言编写程序,是面向对象的。但用数据库都是关系型数据库,存储结构是面向对象的,但是数据库确是关系的,所以在每次存储过着查询数据时,我们都需要做转换。类似Hibernate、Mybatis这样的ORM矿浆确是可以简化这个过程,但是在对高性能查询需求时,这些ORM框架就捉襟见肘了。

1.NoSQL数据库类型

(1)键值(key-value)数据库(Redis/Memcached)

适用场景:存储用户信息,比如会话、配置文件、参数、购物车等。这些信息一般都和ID(键)挂钩,这周情境下键值数据库是个很好的选择。

(2)面向文档(Document-Oriented)数据库【MongoDB】ES

数据可以使用xml、json或者jsonb等多种形式存储。{"name" : "abc"} ,使用场景:1.日志  2.分析

(3)列存储(Wide Column Store/Conlumn-Family)数据库[HBASE]

列存储数据库将数据储存在列族(column family)中,一个列族存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列族中,而薪资则在另一个列族中。

适用场景:1.日志 2.博客平台,我们储存每个信息到不同的列族中。举个例子,标签可以储存在一个,类别可以在一个,而文章则在另一个。

(4)(Graph-Oriented) 数据库[Neo4J,infoGird]

适用范围很小,主要用网络拓扑分析,入脉脉的人员关系图等。

2.传统RDBMS VS NOSQL

RDBMS(关系型数据库) Mysql

- 高度组织化结构化数据

- 结构化查询语句(SQL)

- 数据和关系都存储在单独的表中。

- 数据操纵语言(DML),数据定义语言(DDL)

- 严格的一致性

-基础事务(ACID)刚性事务特性

NoSQL (非关系性数据库) 

- 代表着不仅仅是SQL

- 没有声明性查询语言,针对 k-v 操作 map 一样操作他

- 没有预定义的模式

- 键 - 值对存储,列存储,文档存储,图形数据库

- 不能完整的支持事务(弱事务)

- 灵活、快速、简单MAP

- 最终一致性,而非ACID【原子,一致,隔离,持久】属性

- 非结构化和不可预知的数据(NoSql 数据比较松散)

- CAP定理 【一致性,可用性,容错性】

- 高性能,高可用性和可伸缩性

总结NoSql

1. NoSql就是为了性能而诞生的。

2. NoSql 是Sql的阉割版本,为了解决行业内特定问题

3.Nosql没有特定的数据结构定义,使用时不需要表

4.NoSql对事物的支持很差

3.常见的NoSql及区别

常见的NoSql数据库

1,Memcached

挥发性(临时性)的键值存储

一般作为关系型数据库的缓存来使用

具有非常快的处理速度

由于存在数据丢失的可能,所以一般用来处理不需要持久保存的数据

用于需要使用expires时(需要定期清除数据)

使用一致性散列(Consistent Hashing)算法来分散数据

 2,Tokyo Tyrant

持久性的键值存储

用来处理需要持久保存,高速处理的数据

具有非常快的处理速度

用于不需要定期清除的数据

使用一致性散列(Consistent Hashing)算法来分散数据

3,Redis

兼具Memcached和Tokyo Tyrant优势的键值存储

擅长处理数组类型的数据

具有非常快的处理速度

可以高速处理时间序列的数据,易于处理集合运算

拥有很多可以进行原子操作的方法

使用一致性散列(Consistent Hashing)算法来分散数据

4,MongoDB

面向无需定义表结构的文档数据

具有非常快的处理速度

通过BSON的形式可以保存和查询任何类型的数据

无法进行JOIN处理,但是可以通过嵌入(embed)来实现同样的功能

使用sharding(范围分割)算法来分散数据

二、Redis简介

1.Redis读取的速度是110000次/s,写的速度是81000次/s使用于现在Web2.0的时代

2.原子性: Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性支持。

3.支持多种数据结构:String(字符串);List(列表);hash(哈希);set(集合);zset(有序集合),key(String)-value

4.持久化:主从复制(集群)

5.支持过期时间,支持事务,消息订阅。

6.官方不支持window,但有第三方版本。

Redis的应用场景:

(1)数据缓存(提高访问性能)

将一些数据在短时间之内不会发生变化,而且它们还要被频繁访问,为了提高用户的请求速度和降低网站的负载,降低数据库的读写次数,就把这些数据放在缓存中

(2)会话缓存(共享session)

(session cache,保存web会话信息)

(3)排行榜/计数器

(NGINX+lua+redis 计数器进行IP自动封装)

(4)消息队列(ActiveMQ/RabbitMQ/Kafka/RocketMQ)

(创建实时消息系统。聊天,群聊)重点做缓存(数据,用户信息)

(5)单进程单线程

采用I/O多路复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)

why?

多线程处理可能会涉及到锁(加锁是比较慢)

多线程处理会涉及到线程切换而消耗CPU jvm PC寄存器 一次cpu调度线程上下文切换(1500ns)

单线程不存在线程安全问题

缺点:无法发挥多核cpu性能,步古沟可以通过在单机开多个Redis实例来完善

为什么用redis?  主要是快,(1.单线程不需要线程切换开销,2.没有锁的竞争,3.IO多路复用)tcp/upd五层协议

三、Redis的数据类型

概述:使用Redis进行应用设计和开发的一个核心概念是数据类型。与关系数据库不同,在Redis中不存在需要我们担心的表,在使用Redis进行应用设计和开发时,我们首先应该考虑的是Redis原生支持的哪种数据类型适合我们的应该场景,此外,我们无法像在关系数据库中那样,使用sql来操作Redis中的数据,相反,我们需要直接使用API发送对应的命令,来操作想要操作的数据​​​​​。

1.字符串类型Map<String,String>

    字符串类型是编程语言和应用程序中最常见和最有用的数据类型,也是Redis的基本数据类型之一,事实上,Redis中所有键都必须是字符串

2.list数据类型Map<String,List<String>>

    列表是应用我只是应该程序开发中非常有用的数据类型之一,列表能存在一组对象,因此它也可以被用于栈或者队列,在Redis中,与键相关的联的值可以是字符串组成的列表,Redis中的列表更像是数据结构中的双向链表。

​​​​​​​3.hash数据类型Map<String,Map<String,String>>

    哈希表示字段和值之间的映射关系,与JAVA中的Map类似,Redis数据集本身就可以看做一个哈希,其中字符串类型的键关联到如字符串和列表之类的数据对象,而Reidis的数据对象也可以再次使用哈希,其字段和值必须 是字符串。

​​​​​​​4.set数据类型Map<String,Set<String,String>>

    集合类型是由唯一,无序对象组成的集合(collection).它经常用于测试某个成员是集合中,重复项删除和集合运算(求并,交,差集),Redis的值对象可以是字符串集合。

​​​​​​​5.zset(sortset)数据类型

    有序集合是一个类似于set但是更复杂的数据类型,单词sorted意为着这种集合中的每个元素都有一个可用于排序的权重,并且我们可以按顺序从集合中得到元素在某些需要一个保持数据有序的场景中,使用这种原生的序的特性是很方便的。

四、Redis 的持久化

​​​​​​​什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

  (Redis 数据都放在内存中。如果机器挂掉,内存的数据就不存在。所以需要做持久化,将内存中的数据保存在磁盘,下一次启动的时候就可以恢复数据到内存中。)

Redis 提供了两种持久化方式:RDB(默认) 和AOF 。

RDB (快照): 

  Redis可以通过创建快照来 获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis读性能),还可以将快照留在原地以便重启服务器的时候使用。

快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

AOF(只追加文件):  

  与快照持久化相比,AOF持久化的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:appendonly yes

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof。  config get dir

  在Redis的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度

appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘

appendfsync no #让操作系统决定何时进行同步

  为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

RDB (快照):快照形式 ,定期将当前时刻的数据保存磁盘中。会产生一个dump.rdb文件

特点:性能较好,数据备份。但可能会存在数据丢失。

AOF(只追加文件) :append only file (所有对redis的操作命令记录在aof文件中),恢复数据,重新执行一遍即可。

特点:每秒保存,数据比较完整。但耗费性能。  

  【注】如果两个都配了优先加载AOF。(同时开启两个持久化方案,则按照 AOF的持久化放案恢复数据。)

​​​​​​​五、Redis 的架构模式

主从模式(redis2.8版本之前的模式)、哨兵sentinel模式(redis2.8及之后的模式)、redis cluster模式(redis3.0版本之后)

​​​​​​​​​​​​​​什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤

3:也可以使用流行的bloom filter布隆过滤器

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

缓存击穿

当一个热点key 突然过期了,此时有大量请求进来 ,请求会打到数据库 ,数据库就炸了

怎么解决: 热点key 永不过期  set(k1,v2) 每次set值的时候最好给一个过期时间   避免出现淘汰策略

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到