NoSQL数据库_Redis


在线redis
NoSQL是一种不同于关系数据库的数据库管理系统设计方式,是对非关系数据库的统称.它所采用的是数据模型并非传统关系数据库的关系模型,而是类似键值、列族、文档等非关系模型.

一、特点

通常NoSQL数据库具有以下3个特点:
1.灵活的可扩展行
2.灵活的数据模型
3.与云计算紧密融合

二、与关系数据库的比较

  • 关系数据库的优缺点
    优势在于,以完善的关系代数理论为基础,有严格的标准,支持事务ACID四性,借助索引机制可以实现高效的查询,技术成熟,有专业公司技术支持.
    劣势在于可扩展性差,无法较好地支持海量数据存储,数据模型过于死板,无法较好地支持Web2.0应用,事务机制影响了系统的整体性能等.
  • NoSQL数据库的优缺点
    优势在于,可以支持超大数据规模存储,灵活的数据模型可以很好地支持Web2.0应用,具有强大的横向扩展能力等.
    劣势在于,缺乏数学理论基础,复杂查询性能不高,一般都不能实现事务的强一致性,很难实现数据完整性,技术尚不成熟,缺乏专业团队的技术支持,维护较困难等.

对于关系数据库而言,在一些特定应用领域,其地位和作用仍然无法被取代,银行,超市等领域的业务依然需要高度依赖于关系数据库来保证数据的一致性

三、NoSQL的四大类型

1、键值数据库

项目描述
相关产品Redis,Riak
数据模型键/值对
典型应用内容缓存,如会话、配置文件、参数、购物车等
优点扩展性好灵活性好
缺点无法存储结构化信息,条件查询效率较低
使用者百度云数据库(Redis)

2、列族数据库

项目描述
相关产品BigTable, HBase, Cassandra
数据模型列族
典型应用分布式数据存储与管理
优点查找速度快 可扩展性强 容易分布式扩展
缺点功能较少 大都不支持强事务一致性
使用者Ebay(Cassandra) Facebook(HBase)

3、文档数据库

在文档数据库中,文档是数据库的最小单位.虽然每一种文档数据库的部署都有所不同,但是大都假定文档以某种标准化格式封装并对数据进行加密,同时用多种格式进行解码,包括XML,YAML,JSON,BSON等.
文档数据库通过键来定位一个文档,因此可以看成是键值数据库的一个衍生品,而且前者比后者具有更高的查询效率.

项目描述
相关产品MongoDB
数据模型版本化的文档
典型应用存储、索引并管理面向文档的数据或者类似的半结构化数据
优点性能好、灵活性高
缺点缺乏统一的查询语句
使用者百度云数据库MongoDB

4、图数据库

项目描述
相关产品Neo4J
数据模型图结构
典型应用应用于大量复杂、互连接低结构化的场合,如社交网络、推荐系统
优点灵活性高、支持复杂的图算法
缺点复杂性高、只能支持一定的数据规模
使用者Adobe(Neo4J),Cisco,T-Mobile

在这里插入图片描述


最后用一张图形象描述一下上面提到的数据库

在这里插入图片描述

四、NoSQL的三大基石

NoSQL的三大基石包括CAPBASE最终一致性

1.CAP

指的是:

  • C(Consistency):一致性
    它是指任何一个读操作总是能够读到之前完成的写操作的结果,也就是在分布式环境中,多点的数据是一致的。数据在多个副本中能保持一致的状态。
  • A(Availability):可用性
    它是指快速获取数据,可以在确定的时间内返回操作结果。整个系统在任何时刻都能提供可用的服务,通常达到99.99%四个九可以称为高可用。
  • P(Tolerance of Network Partition,Partition Tolerance ):分区容忍性
    它是指当出现网络分区的情况时(即系统中的一部分节点无法和其他节点进行通信),分离的系统也能够正常运行。

CAP理论的核心是: 一个分布式系统不可能同时很好地的满足一致性、可用性、分区容忍性. 最多只能同时较好的满足两个。

CA:单点集群,满足一致性,可用性的系统,通常在可扩展上不太强大。应用:传统的Oracle数据库.

CP:满足一致性,分区容错性的系统,通常性能不是特别高。应用:Redis,MongoDB,银行.

AP:满足可用性,分区容错性,通常可能对一致性要求低一些。应用:大多数网站架构的选择.一般弱一致性即可.
在这里插入图片描述

为何CAP三者不可兼得

http://codekiller.top/2020/03/30/redis2/

2.BASE

Base就是为了解决关系型数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。
在这里插入图片描述
BASE的基本含义是基本可用(Basically Availble)、软状态(Soft-state)、最终一致性(Eventual-consistendy)。下面分别介绍:
(1)基本可用
指一个分布式系统的一部分发生问题变得不可用时,其他部分仍然可以正常使用,也就是允许分区失败的情形出现.

(2)软状态

  • 软状态 Soft-state
    指状态可以有一段时间不同步,具有一定的滞后性.

  • 硬状态 Hard-state
    数据库的状态必须一直保持数据库一致性,就是任意时刻数据必须是正确的.

(3)最终一致性
举例:双十一某个商品本来有100万人点赞,结果只显示了80万,但等高峰过后工程师要保证这个点赞数最终是正确的,这就是最终一致性.

3.最终一致性 (完)

五、数据库分类图

在这里插入图片描述

redis应用场景

https://www.bilibili.com/video/BV1J4411x7U1?p=3
在这里插入图片描述

redis安装

REmote DIctionary Server(远程字典服务器)

Linux redis安装方法一:Docker安装

docker pull redis
docker run -d -p 6379:6379 --name myredis docker.io/redis

db0 到 db15 共16个库:
在这里插入图片描述

Linux redis安装方法二

sudo apt-get install redis-server

执行service redis status 可以查看redis服务的状态为running,说明安装完成系统自动启动了服务.

执行redis-cli命令打开redis客户端:
在这里插入图片描述

select 0 切换库
keys * 显示所有的键值对
set "key" "value" 设置键值对
FLUSHALL 清空所有键值对(所有库中的)

redis配置文件
首先查看redis安装位置,可以看到在/etc/redis目录下

root@user-virtual-machine:/etc/redis# whereis redis
redis: /etc/redis

Windows环境下安装Redis

https://www.cnblogs.com/zxtceq/p/14002736.html

redis常用命令

http://www.redis.cn/commands.html#string

在这里插入图片描述

Redis数据类型

Redis以键值对存储数据:

  • Key只有String类型
  • Value包括五种数据类型:string、hash、list、set、zset(sorted set).
    zset(sorted set)应用: 英雄战力排行榜(60分以上的, 90分以上的).

首先看一下key
在这里插入图片描述

keys *
exists "key的名字":检查key是否存在
expire key的名字 second:为key设定过期时间,以秒计算,可以不写second,默认为秒
ttl key:返回key剩余时间,-1为永久,-2为失效
type key:返回key所储存的值的类型

set k1 v1
set k2 v2
set msg aaa

keys *
1) "k2"
2) "msg"
3) "k1"

> get msg
"aaa"
> exists k1
(integer) 1
> exists k3
(integer) 0

> expire k1 10
(integer) 1
> ttl k1
(integer) 3
> ttl k1
(integer) -2

> get k1
(nil)
> type k1
"none"

> type k2
"string"

expirekey second的使用场景:
1、限时的优惠活动
2、网站数据缓存
3、手机验证码
4、限制网站访客频率

key的命名建议:

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

String

在这里插入图片描述

set/get/del/append/strlen
getrange/setrange 返回 key 中字符串值的子字符
setex(set with expire)键秒值/setnx(set if not exist)

> set k1 abcdefg
OK
> get k1
"abcdefg"
> getrange k1 0 3
"abcd"

> setrange k1 0 qwe
7
> get k1
"qwedefg"

将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)> setex k1 10 qwe
OK
> get k1
"qwe"
> ttl k1
(integer) -2

bitmap

主要用来做活跃用户在线状态、活跃用户统计、用户签到等场景

Redis数据类型String之bitmap
https://blog.csdn.net/qq_36804603/article/details/111599199

Redis BitMap简介(一)
https://www.bilibili.com/video/BV1Vv411s799

list 有点像队列

在这里插入图片描述
底层采用双向链表 左进左出 右进右出

lpush/rpush/lrange

> lpush list0 1 2 3 4 5
(integer) 5

> llen list0
(integer) 5

> lrange list0 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"

在这里插入图片描述

lpop/rpop

> lpop list0 # 左边弹出一个
"5"
> lrange list0 0 -1 
1) "4"
2) "3"
3) "2"
4) "1"

> rpop list0 # 右边弹出一个
"1"
> lrange list0 0 -1
1) "4"
2) "3"
3) "2"

lindex

> lindex list0 0
"4"

llen

> llen list0
(integer) 3

lrem key 删除N个value(删除指定位置的值)

> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "2"
6) "2"
7) "1"
> lrem list1 2 2  # 删除两个2
(integer) 2
> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"

ltrim key 开始index 结束index,截取指定范围的值后再赋值给key

> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "1"
> ltrim list1 0 2 # 去除索引0-2的值, 再赋给list1
OK
> lrange list1 0 -1
1) "5"
2) "4"
3) "3"

应用场景
在这里插入图片描述

set

在这里插入图片描述
在这里插入图片描述
应用场景一: 网站访问量
在这里插入图片描述
解决方法一:
在这里插入图片描述

> sadd iplist 192.168.1.2 # 第一个有用ip
(integer) 1
> sadd iplist 192.168.1.3 # 第二个有用ip
(integer) 1
> sadd iplist 192.168.1.3 # 重复
(integer) 0
> sadd iplist 192.168.1.3 # 重复
(integer) 0
> scard iplist # 获取iplist的元素个数
2

解决方法二: bitset

拼多多面试:如何用 Redis 统计独立用户访问量? - 动力节点Java学院的文章 - 知乎
https://zhuanlan.zhihu.com/p/88995241

Redis getbit和setbit 用法理解https://blog.csdn.net/sinat_38740436/article/details/88599751

hash

在这里插入图片描述
平时Java中写的Bean, User有id跟name属性,这里user是一个key,它的value也是一个键值对(key:name,value:tony)
在这里插入图片描述

> hset user name tony
1
> hget user name
"tony"
> hmset customer id 1 name Tom age 23
OK
> hmget customer id name age
1) "1"
2) "Tom"
3) "23"

> hgetall customer # 返回多个key, value
1) "id"
2) "1"
3) "name"
4) "Tom"
5) "age"
6) "23"

> hkeys customer
1) "id"
2) "name"
3) "age"

> hvals customer
1) "1"
2) "Tom"
3) "23"

应用场景一
在这里插入图片描述
应用场景二
在这里插入图片描述
在这里插入图片描述

zset

在这里插入图片描述

# 60分以上v1个, 70分以上v2个
> zadd zset0 60 v1 70 v2 80 v3 90 v4 100 v5
(integer) 5
> zrange zset0 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
> zrangebyscore zset0 60 90
1) "v1"
2) "v2"
3) "v3"
4) "v4"
> zrangebyscore zset0 60 (90  # 小于90, 不包含90
1) "v1"
2) "v2"
3) "v3"
> zrangebyscore zset0 (60 (90 # 大于60, 小于90, 都不包含
1) "v2"
2) "v3"
> zrem zset0 v5
1
> zrange zset0 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"

应用场景脑图

在这里插入图片描述

Redis持久化

Redis 为了保证效率,数据缓存在了内存中,但是会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件中,以保证数据的持久化。
Redis 的持久化策略有两种:

RDB(Redis DataBase)

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里.

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中 dump.rdb,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。

优缺点:

  • 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
  • RDB的缺点是最后一次持久化后的数据可能丢失。(假如5min一次, 刚备份完后的 1 分钟系统挂掉了, 这就导致最后数据丢失)

fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等). 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程.

AOF(Append Only File)

RDB持久化是用进程将数据写入文件,而AOF持久化则是将每次执行的写命令记录到单独的日志文件中(有点像MySQL的binlog);当Redis重启时再次执行AOF文件中的命令来恢复数据。

与RDB相比,AOF的实时性更好,因此已成为主流的持久化方案。

参考

https://www.cnblogs.com/kismetv/p/9137897.html

Redis事务

常用命令

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 即批处理, 一次性执行一堆命令.

> multi # 标记事务开始
OK
> incr user_id # 多条命令按顺序入队
QUEUED
> incr user_id
QUEUED
> incr user_id
QUEUED
> get user_id
QUEUED
> exec # 执行
1) 1
2) 2
3) 3
4) "3"

悲观锁/乐观锁/CAS(Check And Set)

悲观锁(Pessimistic Lock)
顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.

乐观锁(Optimistic Lock)
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,乐观锁策略:提交版本必须大于记录当前版本才能执行更新.

1 DISCARD
取消事务,放弃执行事务块内的所有命令。

2 EXEC
执行所有事务块内的命令。

3 MULTI
标记一个事务块的开始。

4 UNWATCH
取消 WATCH 命令对所有 key 的监视。

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

三个特性

单独的隔离操作:
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

没有隔离级别的概念:
队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题.

不保证原子性:
redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚.

主从复制

配置方法

配从(库)不配主(库): 只需配置从服务器, 主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。

从节点开启主从复制,有3种方式:

(1)配置文件
在从服务器的配置文件中加入:slaveof

(2)启动命令
redis-server启动命令后加入 --slaveof

(3)客户端命令
Redis服务器启动后,直接通过客户端执行命令:slaveof ,则该Redis实例成为从节点。

主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段;

数据同步阶段:全量复制和部分复制

在Redis2.8以前,从节点向主节点发送sync命令请求同步数据,此时的同步方式是全量复制;在Redis2.8及以后,从节点可以发送psync命令请求同步数据,此时根据主从节点当前状态的不同,同步方式可能是全量复制或部分复制。后文介绍以Redis2.8及以后版本为例。

  • 全量复制:用于初次复制或其他无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作。
  • 部分复制:用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。需要注意的是,如果网络中断时间过长,导致主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制。

命令传播阶段:心跳机制

在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PINGREPLCONF ACK。心跳机制对于主从复制的超时判断、数据安全等有作用。

主从复制虽然解决或缓解了数据冗余、故障恢复、读负载均衡等问题,但其缺陷仍很明显:

  • 故障恢复无法自动化;
  • 写操作无法负载均衡;
  • 存储能力受到单机的限制;

这些问题的解决,需要哨兵和集群的帮助.

更多参考

★★★★★ https://www.cnblogs.com/kismetv/category/1186633.html

哨兵模式

Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。下面是Redis官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

深入学习Redis(4):哨兵
https://www.cnblogs.com/kismetv/p/9609938.html

简书: 多哨兵模式
https://www.jianshu.com/p/06ab9daf921d

缓存穿透,缓存击穿,缓存雪崩

《进大厂系列》系列-Redis缓存雪崩、击穿、穿透
https://zhuanlan.zhihu.com/p/89961333

REDIS缓存穿透,缓存击穿,缓存雪崩原因+解决方案
https://www.cnblogs.com/midoujava/p/11277096.html

保证缓存(redis)与数据库(MySQL)的一致性

https://blog.csdn.net/wwd0501/article/details/106902856/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值