数据库技术
2022-07-30 21:05:19 0 举报
AI智能生成
数据库技术
作者其他创作
大纲/内容
原子性:事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。
一致性:数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。
隔离性:一个事务所做的修改在最终提交以前,对其它事务是不可见的。
持久性:一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 使用重做日志来保证持久性。
丢失修改:T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。
读肮数据:T1 修改一个数据,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。
不可重复读:T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
幻影读:T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次 读取的结果不同。
产生并发不一致性问题主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题。
并发一致性问题
事务中的修改,即使没有提交,对其它事务也是可见的。
未提交读(READ UNCOMMITTED)
一个事务只能读取已经提交的事务所做的修改。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。
提交读(READ COMMITTED)
保证在同一个事务中多次读取同样数据的结果是一样的。
可重复读(REPEATABLE READ)
强制事务串行执行。需要加锁实现,而其它隔离级别通常不需要。
可串行化(SERIALIZABLE)
图示
隔离级别
事务ACID
封锁粒度
排它锁(Exclusive),简写为 X 锁,又称写锁。 共享锁(Shared),简写为 S 锁,又称读锁。
一个事务对数据对象 A 加了 X 锁,就可以对 A 进行读取和更新。加锁期间其它事务不能对 A 加任何锁。 一个事务对数据对象 A 加了 S 锁,可以对 A 进行读取操作,但是不能进行更新操作。加锁期间其它事务能对 A 加 S 锁,但是不能加 X 锁。
1. 读写锁
2.意向锁
封锁类型
事务 T 要修改数据 A 时必须加 X 锁,直到 T 结束才释放锁。 可以解决丢失修改问题,因为不能同时有两个事务对同一个数据进行修改,那么事务的修改就不会被覆盖。
一级封锁协议
在一级的基础上,要求读取数据 A 时必须加 S 锁,读取完马上释放 S 锁。可以解决读脏数据问题,因为如果一个事务在对数据 A 进行修改,根据 1 级封锁协议,会加 X 锁,那么就不能再加 S 锁了,也就是不会读入数据。
二级封锁协议
在二级的基础上,要求读取数据 A 时必须加 S 锁,直到事务结束了才能释放 S 锁。 可以解决不可重复读的问题,因为读 A 时,其它事务不能对 A 加 X 锁,从而避免了在读的期间数据发生改变。
三级封锁协议
1. 三级封锁协议
加锁和解锁分为两个阶段进行。
可串行化调度是指,通过并发控制,使得并发执行的事务结果与某个串行执行的事务结果相同。事务遵循两段锁协议是保证可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。
MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在同一时刻被释放,这被称为隐式锁定。InnoDB 也可以使用特定的语句进行显示锁定:
MySQL 隐式与显示锁定
2.两段锁协议
封锁协议
封锁
列的原子性
第一范式1NF
满足第一范式,必须有主键列
第二范式 2NF
满足第二范式,主外健引用
第三范式3NF
三大范式
约束是表级的强制规定,有以下五中:not null,unique,primary key,foreign key,check 。
完整性约束
ER图
概念模型
关系:二维表
逻辑模型
表结构,包括字段,长度,非空等
物理模型
数据库模型
数据库设计
数据库系统原理
问题1:innoDB是使用主键构建B+TREE的。使用整型会比UUID好很多,比较会减少,内存会较小
InnoDB
索引和数据是分开的。
MyISAM
事务:InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句。 并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。 外键:InnoDB 支持外键。备份:InnoDB 支持在线热备份。崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。 其它特性:MyISAM 支持压缩表和空间数据索引。
MyISANM适合做读库,InnoDB写多读少
比较
存储引擎
B Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。(看图理解)B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高 区间查询的性能。在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不 为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
插入删除操作会破坏平衡树的平衡性,因此在插入删除操作之后,需要对树进行一个分裂、合并、旋转等操作来维护平衡性。
更少查询次数
利用磁盘预读特性
优势
优势劣势的操作
1.数据结构
B+树的数据结构
查找过程
注意 这是mysql B+树检索过程(后面查找过程分析)
B+ Tree 原理
InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被 称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。
辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到 主索引中进行查找。
大多数 MySQL 存储引擎的默认索引类型
1. B+Tree 索引
哈希索引能以 O(1) 时间进行查找,但是失去了有序性: 无法用于排序与分组(重点); 只支持精确查找,无法用于部分查找和范围查找。InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之 上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。
2. 哈希索引
MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。 查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
3. 全文索引
MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据, 可以有效地使用任意维度来进行组合查询。必须使用 GIS 相关的函数来维护数据。
4. 空间数据索引
索引类型(按数据结构分)
数据和索引存储在同一文件中,以主键索引存储数据
表中的行的物理顺序和健值的逻辑(索引)顺序相同,一个表只包含一个聚集索引
聚族索引
数据和索引分开,单独存放在不同的文件中,索引文件不存储数据,而是存储数据的地址。
数据库表中记录的物理顺序和索引顺序可以不相同,一个表可以包含多个非聚集索引
非聚族索引
按物理存储结构分
主键索引
唯一索引
普通索引
单列索引
组合索引
按字段列分
1.最左前缀匹配
2.覆盖索引
让选择性最强的索引列放在前面。索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。
3.索引顺序
字符串 不要忘了“” ,
like % 不要写最前
where 后索引列 不能计算
where对null判断where不等于
注意事项
索引优化
explain 分析
SQL执行计划
1.切分大查询
2.切分大连接查询
重构查询方式
索引是mysql高效获取数据的排好序的数据结构。
为什么选择B+树作为索引结构
索引
水平切分又称为 Sharding,它是将同一个表中的记录拆分到多个结构相同的表中。 当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。
水平切分
垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。
垂直切分
哈希取模:hash(key) % N;
映射表:使用单独的一个数据库来存储映射关系。
范围:可以是 ID 范围也可以是时间范围;
Sharding 策略
1. 事务问题 使用分布式事务来解决,比如 XA 接口。
2. 连接 可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。
3. ID 唯一性使用全局唯一 ID(GUID)为每个分片指定一个 ID 范围分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)
Sharding 存在的问题
切分
主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。binlog 线程 :负责将主服务器上的数据更改写入二进制日志(Binary log)中。I/O 线程 :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。SQL 线程 :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。
子主题
主从复制
主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作。读写分离能提高性能的原因在于:主从服务器负责各自的读和写,极大程度缓解了锁的争用; 从服务器可以使用 MyISAM,提升查询性能以及节约系统开销; 增加冗余,提高可用性。读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。
读写分离
复制
添加一行:alter table apple add red varchar[50];修改表名: rename table apple To banana修改列名:alter table apple change red green int ;修改一个表的字段类型:alter table apple modify red varchar(50);查看表的字段信息:desc apple;删除一列:alter table apple drop red;
DDL:数据定义语言
DML:数据操作语言
DQL:数据查询语言
grant all privileges on 数据库名.表明(所有:*.*) To 用户名 identify by '密码'(with grant option——给与其给别人权限的权限);
权限
外连接
自连接
子查询
创建视图:create view name as();修改视图:create or replace view name as ();删除视图:drop view name ;algorithm:替代式:merge 具化式:temptable (更安全)with check option 更新数据时进行检测create algorithm view name as (conditon) with check option;视图不可更新部分:不是来自于基表
视图
语法顺序:select -> distinct -> from -> join on -> where -> group by -> having -> union-> order by
执行顺序: from->where ->group by ->having->select ->distinct ->union ->order by
SQL执行顺序
SQL基础
数据类型
如何实现 MySQL 的读写分离?
MySQL 主从复制原理的是啥?
MySQL 主从同步延时问题(精华)
Mysql的逻辑结构
undoLog
redoLog
MVCC多版本并发控制
binlog
binlog和redolog的区别
InnoDB的行锁模式
面试
负向查询不能使用索引
前导模糊查询不能使用索引
字段的默认值不要为 null
在字段上进行计算不能命中索引
最左前缀问题
如果明确知道只有一条记录返回
不要让数据库帮我们做强制类型转换
如果需要进行 join 的字段两表的字段类型要相同不然也不会命中索引。
数据区分不明显的不建议创建索引
SQL优化
扩展
mysql
切换数据库
创建数据库
数据库为空,则在show时不显示
所有修改数据库操作基于mydb
use mydb
查看所有数据库
show dbs
查看当前use的数据库
db
删除数据库
db.dropDatabase()
database操作
所有操作基于数据库mydb执行
删除集合
db.collection.drop()
collection操作
所有操作基于数据mydb执行
db.mycol.insert({\"key\" : \"value\"})
myvar=({\"key\" : \"val\"})
db.mycol.insert(myvar)
数据插入
查看collection下所有document
{<key>:<value>}
等于
{<key>:{$lt:<value>}}
小于\t
{<key>:{$lte:<value>}}
小于或等于
{<key>:{$gt:<value>}}
大于
{<key>:{$gte:<value>}}
大于或等于
{<key>:{$ne:<value>}}
不等于
大于并小于
{\"key1\" : \"value1\
key1 = value2 and key2 = value2
and
{ \"key\" : \"value\
key = value and ( key1 = value1 or key2 = value2)
or
逻辑条件
Double : 1
String : 2
Object : 3
Array : 4
Binary data : 5
已废弃
Undefined : 6
Object id : 7
Boolean : 8
Date : 9
Null : 10
Regular Expression : 11
JavaScript : 13
Symbol : 14
JavaScript (with scope) : 15
32-bit integer : 16
Timestamp : 17
64-bit integer : 18
使用-1
Min key : 255
Max key : 127
类型映射
db.col.find({<key> : { $type : 2}} )
类型条件
limit(number)
指定查询返回记录数
limit
skip(number)
指定从记录数中跳过前number条记录
skip
查询数量限制
1- 升序排序
-1 - 降序排序
sort({<key> : 1})
查询排序
db.col.find()
db.col.find().pretty()
数据查找
查询条件
<query>
更新字段及结果
<update>
可选,若不存在,true-插入;false-不插入
upsert
可选,true-只更新查找到的第一条记录;false-更新所有查找到的记录
multi
可选,抛出异常的级别
writeConcern
document完整文档数据,需要指明id进行更新
数据更新
可选,查询条件
可选,默认为false,true-只删除一条;false-删除所有记录
justOne
span style=\
数据删除
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$project
用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$match
用来限制MongoDB聚合管道返回的文档数
$limit
在聚合管道中跳过指定数量的文档,并返回余下的文档
$skip
将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
$unwind
select sum(group_by_key) * num as output_key from col group by group_by_key
$sum
$avg
$min
db.mycol.aggregate({$group : {_id : \"$span style=\
$max
aggregate([{$group : {_id : \"$title_var\
将聚合输出的avg_key转化为数组
$push
aggregate([{$group : {_id : \"$span style=\
在结果文档中插入值到一个数组中,但不创建副本。
$addToSet
aggregate([{$group : { _id : \"$span style=\
根据资源文档的排序获取第一个文档数据。
$first
根据资源文档的排序获取最后一个文档数据
$last
操作
$group
将输入文档排序后输出
$sort
输出接近某一地理位置的有序文档
$geoNear
聚合操作
document操作
1-升序
2-降序
排序
true-在后台创建索引,执行期间不阻塞其他操作
false-默认,执行期间阻塞其他操作
font color=\"#333333\" face=\
background
true-唯一索引
false-默认,非唯一索引
unique
string-索引的名称。若未指定,通过过连接索引的字段名和排序顺序生成一个索引名称
name
true-删除,创建唯一索引
false-默认,创建非唯一索引
bool,创建唯一索引时删除重复记录
dropDups
true-在索引字段中不会查询出不包含对应字段的文档
false-默认
bool,对文档中不存在字段数据不启用索引
sparse
expireAfterSeconds
索引的版本号,默认的索引版本取决于mongod创建索引时运行的版本。
v
weights
对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语。
default_language
对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language。
language_override
创建索引
集合中索引不能超过64个
索引名的长度不能超过125个字符
一个复合索引最多可以有31个字段
范围
正则表达式及非操作符
算术运算符
$where 子句
不能使用索引
index
1~4字节
时间戳
5~7字节
机器标示码
8~9字节
进程ID
10~12字节
随机数
格式
ObjectId
数据库名称
集合名称
ref
引用id
id
DBRef
mongo.dml
Mongodb
字典(散列表)
跳跃表是有序集合的底层实现之一。
数据结构
set key value
设置置顶key的值
set
get key
获取指定key的值
get
incr key
将key中储存的数字值增一
incr
decr key
将key中储存的数字值减一
incrby key decrement
key 所储存的值增加给定的减量值(decrement)
incrby
decrby key decrement
key 所储存的值减去给定的减量值(decrement)
decrby
append key value
如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
append
setnx key value
只有在 key 不存在时设置 key 的值
setnx
mget key [key...]
获取所有(一个或多个)给定 key 的值。
mget
mget key value [key value ...]
同时设置一个或多个 key-value 对
mset
getset key value
将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
getset
setex key seconds value
将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
setex
strlen key
返回 key 所储存的字符串值的长度
strlen
del key
删除键
del
单值缓存
使用更简单
set user:1 json数据格式
这种方式更好,当对象需要某个值的
mset user:1:name zhangsan user:1:age 22
对象缓存
分布式锁
微信文章阅读数量,当打开文章的incr article:readcount:1001 实现加一
获取直接用get article:readcount:1001(文章id)
计数器
spring session的实现使用该数据结构
分布式系统全局序列号
操作场景
String类型操作 [key|value(string/int/float)]
srem key field value
将哈希表 key 中的字段 field 的值设为 value
hset
hmset key field1 value1 [field2 value2]
同时将多个 field-value (域-值)对设置到哈希表 key 中
hmset
hsetnx key field value
只有在字段 field 不存在时,设置哈希表字段的值
hsetnx
hget key field
获取存储在哈希表中指定字段的值
hget
hget key field1 [field2]
获取所有给定字段的值
hmget
hgetall key
获取在哈希表中指定 key 的所有字段和值
hgetall
hvals key
获取哈希表中所有值
hvals
hlen key
获取哈希表中字段的数量
hlen
hkeys key
获取所有哈希表中的字段
hkeys
hdel key field1 [field2]
删除一个或多个哈希表字段
hdel
hexitst key field
查看哈希表 key 中,指定的字段是否存在
hexitst
hmset person (用户id):age 20 (用户id):sex man
购物车
优点缺点
Hash类型操作key-> key1 value(string/int/float) key2 value(string/int/float) key3 value(string/int/float) key4 value(string/int/float)
lpush key value1 [value2....]
将一个或多个值插入到列表头部
lpush
rpush key value1 [value2....]
将一个或多个值插入到列表尾部
rpush
push
lpop key
移出并获取列表的第一个元素
lpop
rpop key
移出并获取列表的最后一个元素
rpop
brpop
pop
lrange key start stop
获取列表指定范围内的元素(可用来简单分页)
lrange
llen key
获取列表长度
llen
lindex key index
通过索引获取列表中的元素
lindex
从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT
count > 0
从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值
count < 0
移除表中所有与 VALUE 相等的值
count = 0
lrem key count value
移除列表元素
lrem
lset key index value
通过索引设置列表元素的值
常用数据结构,栈,队列,阻塞队列
小用户量
微博微信公众号消息流
场景应用
List类型操作[key => value1 | 自 value2 | 左 value3 | 而 value4 | 右]
sdd key member1 [member2]
向集合添加一个或多个成员(存在则返回0)
sadd
scard key
获取集合的成员数
scard
sinter key1 [key2]
返回给定所有集合的交集
sinter
sdiff 差集,sunion 并集
sismember key member
判断 member 元素是否是集合 key 的成员
sismember
smembers key
返回集合中的所有成员
smembers
srandmember key [count]
返回集合中一个或多个随机数
srandmember
srem key member1 [member2]
移除集合中一个或多个成员
srem
key 活动id
微信小程序抽奖
微信微博点赞
微信微博关注模型
使用场景
使用
Set类型操作key->[ value1 value2 value3 value4 ]
zadd key score1 member1 [score2 member2....]
向有序集合添加一个或多个成员,或者更新已存在成员的分数
zadd
zcard key
获取有序集合的成员数
zcard
zcount key min max
计算在有序集合中指定区间分数的成员数
zcount
zincrby key increment member
有序集合中对指定成员的分数加上增量 increment
zincrby
zrange key start stop [withscores]
通过索引区间返回有序集合成指定区间内的成员
zrange
zrank key member
返回有序集合中指定成员的索引
zrank
zrem key member1 [member2....]
移除有序集合中的一个或多个成员
zrem
zrevrange key start stop [withscores]
返回有序集中指定区间内的成员,通过索引,分数从高到底
zrevrange
zscore key member
返回有序集中,成员的分数值
zscore
sorted set 是排序的 set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。
Sorc Set类型操作key-> score(10.1) value(string/int/float) rank:1 score(9.1) value(string/int/float) rank:0 score(11.2) value(string/int/float) rank:2
会话缓存(Session Cache)
全页缓存(FPC)
缓存
队列
数据存储
排行榜/计数器
发布/订阅
JedisPool资源池优化
Redis的应用场景
redis基础知识
Redis 可以为每个键设置过期时间,当键过期时,会自动删除该键。 对于散列表这种容器,只能为整个键设置过期时间(整个散列表),而不能为键里面的单个元素设置过期时间。
键的过期时间
可以设置内存最大使用量,当内存使用量超出时,会施行数据淘汰策略。
数据淘汰策略
发布订阅
在redis.conf 有如下配置
过程总结
原理
用户执行SAVE或BGSAVE命令
注意
RDB 持久化
redis4.0优化
流程
AOF 重写
AOF 持久化
持久化
原子性问题
效率问题
Lua
Redis中使用Lua脚本
官网
当Redis连接处于MULTI请求的上下文中时,所有命令都将回复该字符串QUEUED(从Redis协议的角度来看,这是作为状态回复的发送)。当EXEC被调用时,queued命令被有计划地执行。
在 EXEC 之后发生的错误不是以一种特殊的方式处理的:即使某些命令在事务中失败,所有其他的命令也会被执行。
Redis不支持回滚
事务阶段
使用WATCH来实现ZPOP
WATCH命令
乐观锁
Redis事务命令
乐观锁定使用check-and-set
事务
pipeline的思想
pipelineVS脚本
pipelineVS事务
通过Jedis操作pipeline
小总结
pipeline
Redis 服务器是一个事件驱动程序。
文件事件
时间事件
事件的调度与执行
套接字
概念
事件
配置
全量复制
增量复制
无硬盘复制
sentinel之间的相互感知
master的故障发现
哨兵机制
分片
Redis的数据分区
HashTags
重定向客户端
分片迁移
Redis-Cluster
Redis CAS乐观锁实现
特性
可以对 String 进行自增自减运算,从而实现计数器功能。Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。
例如 DNS 记录就很适合使用 Redis 进行存储。查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。
查找表
List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息 不过最好使用 Kafka、RabbitMQ 等消息中间件。
消息队列
可以使用 Redis 来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。
会话缓存
在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
Set 可以实现交集、并集等操作,从而实现共同好友等功能。 ZSet 可以实现有序性操作,从而实现排行榜等功能。
其它
jedis
Redisson
客户端使用
redis实现分布式限流
简介:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决办法(中华石杉老师在他的视频中提到过,视频地址在最后一个问题中有提到):事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉事后:利用 redis 持久化机制保存的数据尽快恢复缓存
缓存雪崩
简介:一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决办法: 有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
缓存穿透
所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺序不同,这样也就导致了结果的不同
推荐一种方案:分布式锁(zookeeper 和 redis 都可以实现分布式锁)。(如果不存在 Redis 的并发竞争 Key 问题,不要使用分布式锁,这样会影响性能)
如何解决 Redis 的并发竞争 Key 问题
不使用的方案
最终一致性的解决方案
如何保证缓存与数据库双写时的数据一致性?
redis 持久化机制
怎么保证 redis 挂掉之后再重启数据可以进行恢复
为什么要用 redis 而不用 map/guava 做缓存?
主要从“高性能”和“高并发”这两点来看待这个问题。
为什么要用 redis/为什么要用缓存
解决方案
redis 和 memcached 有啥区别?
解释
文件事件处理器
redis 的线程模型
为啥 redis 单线程模型也能效率这么高?
redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?
redis 过期策略
内存淘汰机制
思路2
手写一个 LRU 算法
redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?
比较Redis 与 Memcached
部分笔记
redis replication 的核心机制
图示+ 解释
主从复制的断点续传
无磁盘化复制
过期 key 处理
redis 主从复制的核心原理
解释+图示
heartbeat
异步复制
复制的完整流程
Redis 主从架构+原理
redis 如何才能做到高可用
哨兵的介绍
哨兵的核心知识
异步复制导致的数据丢失
脑裂导致的数据丢失
数据丢失问题的解决方案
redis 哨兵主备切换的数据丢失问题
sdown 和 odown 转换机制
哨兵集群的自动发现机制
slave 配置的自动纠正
slave->master 选举算
quorum 和 majority
configuration epoch
configuration 传播
Redis 哨兵集群实现高可用
redis 持久化的两种方式
RDB 优缺点
AOF 优缺点
RDB 和 AOF 到底该如何选择
Redis的持久化机制
redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
集中式
gossip 协议
节点间的内部通信机制
判断节点宕机
从节点过滤
从节点选举
与哨兵比较
redis cluster 的高可用与主备切换原理
ping 消息深入
redis cluster 介绍
hash 算法
一致性 hash 算法
redis cluster 的 hash slot 算法
分布式寻址算法
redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?
事中解决方案解析
缓存击穿
了解什么是 redis 的雪崩、穿透和击穿?redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 redis 的穿透?
Cache Aside Pattern
最初级的缓存不一致问题及解决方案
高并发的场景下,该解决方案要注意的问题
解决方案如下
比较复杂的数据不一致问题分析
如何保证缓存与数据库的双写一致性?
Redis: 分布式锁的正确实现方式( Java 版 )
解决
redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗?
思路
生产环境中的 redis 是怎么部署的?
为什么我们做分布式使用Redis?
redis
数据库技术
0 条评论
回复 删除
下一页