数据库面试题 MySQL数据库面试题(2020最新版)
mysql为什么要用自增id作为主键 为什么要使用自增ID作为主键
直接原因是其存储机制。MySQL采用数据页进行数据存储。如果采用自增主键,在原先数据页写满的情况下,MySQL对于新数据,直接开辟新页进行写操作。如果不采用自增主键,为保障索引有序,新数据需插入到合适位置上,由此针对页数据满的情况下,MySQL需要申请新页,并将一部分之前的页数据挪到新页上,保证按索引有序存储,相对自增主键IO开销更大。
select count 1 和 select count 字段 有什么区别 ? Select count(*)、Count(1)、Count(0)的区别和执行效率比较
1)结果区别
a、count(1) 会统计表中的所有的记录数,包含字段为null 的记录。
b、count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。
2)效率区别
a、列名为主键,count(列名)会比count(1)快
b、列名不为主键,count(1)会比count(列名)快
最好的前几个查询 第二高的薪水、SQL查询语句中的 limit 与 offset 的区别
SQL分页查询语句?MySql实现分页查询的SQL,mysql实现分页查询的sql语句
select * from table limit (start-1)*limit,limit; 其中start是页码,limit是每页显示的条数
Mysql limit过大如何优化 mysql limit分页(偏移量)过大时优化问题
大数据量的分页查询怎么优化 MySQL大数据量分页查询方法及其优化
跨表分页查询怎么做 “跨库分页”的四种方案
SQL通配符匹配查询?MySQL模糊查询?Mysql| 使用通配符进行模糊查询(like,%,_)
1)%百分号通配符: 表示任何字符出现任意次数 (可以是0次).
2)_下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符.
3)LIKE作用:指示mysql后面的搜索模式是利用通配符而不是直接相等匹配进行比较.
4)通配符的使用
a、匹配以"yves"开头的记录:(包括记录"yves")
SELECT * FROM products WHERE products.prod_name like ‘yves%’;
b、匹配包含"yves"的记录(包括记录"yves")
SELECT * FROM products WHERE products.prod_name like ‘%yves%’;
c、匹配以"yves"结尾的记录(包括记录"yves",不包括记录"yves ")
SELECT * FROM products WHERE products.prod_name like ‘%yves’;
一条sql语句是怎么执行的? 一条SQL语句在MySQL中执行过程全解析
数据库架构面试问题 拼多多面试问了数据库基础知识,今天分享出来
MySQL数据更新过程? mysql 一次数据更新过程(undo redo binlog 内存缓冲池扮演了什么角色)
MySQL存储引擎有哪些?Innodb和MyISAM的区别? Mysql 存储引擎的区别和比较
MySQL事务和隔离级别 深入理解 MySQL 事务:隔离级别、ACID 特性及其实现原理
1)事务定义:事务(Transaction)是数据库中各种数据项的一个程序执行单元
2)事务特性:
a、原子性(Atomicity)
定义:原子性,是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做
实现:undo log属于逻辑日志,它记录的是 SQL 执行的相关信息。当发生回滚时,InnoDB 会根据undo log的内容做与之前相反的工作。
b、一致性(Consistency)
定义:数据库前后状态保证一致
实现:通过其他三个特性保证
c、隔离性(Isolation)
定义:隔离性,是指事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰
实现:数据库并发场景如下
(一个事务)读操作对(另一个事务)读操作的影响:不存在任何问题,也不需要并发控制
(一个事务)写操作对(另一个事务)写操作的影响:锁机制保证隔离性
(一个事务)写操作对(另一个事务)读操作的影响:MVCC 保证隔离性
d、持久性(Durability)
定义:持久性,是指事务一旦提交,它对数据库的改变就应该是永久性的。
实现:redo log。如果 MySQL 宕机,重启时可以读取redo log中的数据,对数据库进行恢复
3)写操作对读操作的影响
a、脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。
b、不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。
c、幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。
4)事务隔离级别
a、读未提交(Read Uncommited)存在脏读、不可重复读、幻读
b、读已提交(Read Commited)存在不可重复读、幻读(Oracle)
c、可重复读(Repeatable Read)存在幻读(MySQL)
d、可串行化(Serializable)
MVCC机制?当前读和快照读? 【MySQL笔记】正确的理解MySQL的MVCC及实现原理
1)MVCC定义:MVCC(Multi-Version Concurrency Control)多版本并发控制
MVCC就是为了实现读-写冲突不加锁,而这个读指的是快照读, 而非当前读,当前读实际是一种加锁的操作。
MVCC模型在MySQL中的具体实现则是由 3个隐式字段,undo日志 ,Read View 等去完成的。
2)当前读和快照读
a、当前读
就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁
b、快照读
不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑。
3)实现机制
a、隐式字段
定义:每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段
①、DB_TRX_ID:
6byte,最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID
②、DB_ROLL_PTR:
7byte,回滚指针,指向这条记录的上一个版本(存储于rollback segment里)
③、DB_ROW_ID:
6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
b、undo日志
定义:不同事务或者相同事务的对同一记录的修改,会导致该记录的undo log成为一条记录版本链表
①、insert undo log
代表事务在insert新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
②、update undo log
事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
c、Read View(读视图)
定义:事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID
4)RC和RR下的区别
MVCC只作用在RC和RR两个级别。
在RC隔离级别下,是每个快照读都会生成并获取最新的Read View,所以可能读到数据不一样
而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View,所以读到的数据都一样,解决了不可重复读。
4)MVCC优点
a、可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
b、同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题
MVCC能解决幻读吗?【MySQL】面试题之:MVCC能否解决幻读?
幻读分当前读和快照读两种情况:
1)当前读下的幻读
通过next key lock解决,所谓的next key lock就是一个行锁(record lock)+范围锁(gap lock)
2)快照读下的幻读
MVCC可以解决
MySQL乐观锁和悲观锁区别和实现方式?面试必备之乐观锁与悲观锁
如何实现无锁队列?锁、CAS操作和无锁队列的实现
MySQL的锁有哪些? MySQL锁详解、【MySQL】MySQL有几种锁
1)锁属性:共享锁、排他锁、意向共享锁、意向排他锁
2)锁粒度:全局锁、表级锁、页级锁、行级锁
3)行锁:临键锁(Next-key Lock)=间隙锁+记录锁 [1,4]
间隙锁(Gap Lock)(1,4]、记录锁(Record Lock)1和4
MySQL索引类型有哪些?聚簇索引和非聚簇索引? 【数据库索引Index系列】数据库索引,这一篇就够了
1)普通索引:允许被索引的数据列包含重复值
2)唯一索引:保证索引数据列的唯一性
a、主键索引:一种特殊的唯一索引
b、聚簇索引:在InnoDB中主键索引是聚簇索引
c、非聚簇索引:在MyISAM中主键索引是非聚簇索引
3)联合索引:覆盖多个数据列
4)全文索引:倒排索引ES
索引的实现方式有哪些?数据库常见索引解析(B树,B-树,B+树,B*树,位图索引,Hash索引)
MySQL索引的数据结构 MySQL索引原理及BTree(B-/+Tree)结构详解
适合建索引和不适合建索引的情况? 哪些情况下适合建索引,哪些情况下不适合建索引
1)哪些情况下适合建索引
a、频繁作为where条件语句查询的字段
b、联字段需要建立索引,例如外键字段,student表中的classid, classes表中的schoolid 等
c、序字段可以建立索引
d、组字段可以建立索引,因为分组的前提是排序
e、统计字段可以建立索引,例如count(),max()
2)哪些情况下不适合建索引
a、频繁更新的字段不适合建立索引
b、where条件中用不到的字段不适合建立索引
c、表数据可以确定比较少的不需要建索引
d、数据重复且发布比较均匀的的字段不适合建索引(唯一性太差的字段不适合建立索引),例如性别,真假值
e、与列计算的列不适合建索引
联合索引的数据结构是什么? 联合索引在B+树上的存储结构及数据查找方式
为什么MySQL索引用B+树而不是B树或红黑树?因为红黑树不支持范围查询 为什么Mysql用B+树做索引而不用B-树或红黑树
为什么MySQ索引用B+树而不用哈希表? 为什么mysql索引用B+树而不用哈希表?
索引下推ICP MySQL中的索引下推、mysql索引下推(ICP)例子
MySQL主从复制 MySQL主从复制(异步复制与半同步复制)
1)MySQL主从复制
a、原理:将主服务器的binlog日志复制到从服务器上执行一遍,达到主从数据的一致状态。
b、过程:从库开启一个I/O线程,向主库请求Binlog日志。主节点开启一个binlog dump线程,检查自己的二进制日志,并发送给从节点;从库将接收到的数据保存到中继日志(Relay log)中,另外开启一个SQL线程,把Relay中的操作在自身机器上执行一遍
c、优点:作为备用数据库,并且不影响业务,可做读写分离,一般是一个写库,一个或多个读库,分布在不同的服务器上,充分发挥服务器和数据库的性能,但要保证数据的一致性
d、从库复制状态:为保证从库重启后,仍然知道从哪里开始复制,从库默认会创建两个文件master.info和relay-log.info,分别记录了从库的IO线程当前读取主库binlog的进度和SQL线程应用Relay-log的进度
e、biglog格式:日志格式就是指二进制日志的三种格式,基于语句statement的复制、基于行row的复制、基于语句和行(mix)的复制。其中基于row的复制方式更能保证主从库数据的一致性,但日志量较大,在设置时考虑磁盘的空间问题。
f、binlog刷盘:有sync_binlog=n这一参数,他的值表示每进行n次事务提交,MySQL就将Binlog刷新到磁盘。如果这个值为1,就代表每提交一次事务(SQL),就将Binlog往磁盘刷新一次,这样一来,就算数据库宕机了,那么最多只能损失一次事务的数据。
2)主从复制架构
a、一主多从
在主库的请求压力非常大时,可通过配置一主多从复制架构实现读写分离,把大量对实时性要求不是很高的请求通过负载均衡分发到多个从库上去读取数据,降低主库的读取压力
b、多级复制
①、原理:多级复制架构只是在一主多从的基础上,在主库和各个从库之间增加了一个二级主库Master2,这个二级主库仅仅用来将一级主库推送给它的BInlog日志再推送给各个从库,以此来减轻一级主库的推送压力。
②、缺点:Binlog日志要经过两次复制才能到达从库,增加了复制的延时。
③、解决:在二级从库上应用Blackhol存储引擎(黑洞引擎)来解决这一问题,降低多级复制的延时。“黑洞引擎”就是写入Blackhole表中数据并不会写到磁盘上,所以这个Blackhole表永远是个空表,对数据的插入/更新/删除操作仅在Binlog中记录,并复制到从库中去。
c、双主复制
为了避免主节点挂了后再恢复数据不一致需要重复添加环境的问题,两个数据库互为主从,当主库宕机恢复后,由于它还是原来从库(现在主库)的从机,所以它还是会复制新的主库上的数据。那么无论主库的角色怎么切换,原来的主库都不会脱离复制环境。
3)主从复制方式
a、同步复制:master的变化,必须等待slave-1,slave-2,…,slave-n完成后才能返回。
b、异步复制:master只需要完成自己的数据库操作即可,至于slaves是否收到二进制日志,是否完成操作,不用关心。MYSQL的默认设置。
c、半同步复制:
①、同步个数:master只保证slaves中的一个接收到Binlog并成功写入Relay-log中,就返回,其他slave不管。
②、同步时机:主库不会等待从库执行完Relay-log后才返回,而是确认从库接收到Binlog,达到主从Binlog同步的目的后就返回了,所以从库的数据对于主库来说还是有延时的,这个延时就是从库执行Relay-log的时间。所以只能称为半同步。
MySQL如何实现高可用? MySQL高可用架构对比,MMM与MHA以及MGR、几种MySQL高可用方案整理
1)主从复制+读写分离
客户端通过Master对数据库进行写操作,slave端进行读操作,并可进行备份。
Master出现问题后,可以手动将应用切换到slave端。
2)MySQL Cluster(集群)
MySQL Cluster 由一组计算机构成,每台计算机上均运行着多种进程,包括 MySQL 服务器,NDB Cluster的数据节点,管理服务器,以及(可能)专门的数据访问程序。
MySQL分库分表 彻底搞清分库分表(垂直分库,垂直分表,水平分库,水平分表)、MySQL分库分表
MySQL二进制日志和事务日志 彻底搞懂MYSQL三大日志redo log undo log bin long
binlog 日志是 master 推的还是 salve 来拉的?Master主动向Slave发送binlog还是Slave主动向Master要binlog
MySQL通用查询日志和慢查询日志 关于MySQL 通用查询日志和慢查询日志分析
SQL调优如何调优 数据库SQL调优的几种方式、sql优化的几种方式
SQL慢可能存在什么问题?一条sql执行很慢,可能是因为什么? 怎么优化?、sql 查询慢的48个原因分析(分享)、常见Mysql的慢查询优化方式
Redis面试题 Redis面试题(2020最新版)
Redis的基础数据结构?redis的五种数据结构原理分析
1)字符串(String)底层是c中的字符数组
a、redis对于KV的操作效率很高,可以直接用作计数器。例如,统计在线人数等
b、string类型是二进制存储安全的,所以也可以使用它来存储图片,甚至是视频等。
2)哈希(Hash)哈希结构相当于在value里又套了一层kv型数据
a、一般可以用来存某个对象的基本属性信息,例如,用户信息,商品信息等
b、由于hash的大小在小于配置的大小的时候使用的是ziplist结构,比较节约内存,所以针对大量的数据存储可以考虑使用hash来分段存储来达到压缩数据量,节约内存的目的。
3)列表(List)ziplist+linkedlist+quicklist
可以用于实现消息队列,也可以使用它提供的range命令,做分页查询功能。
4)集合(Set)底层为散列表hashtable
a、可以用作某些去重功能,例如用户名不能重复等。
b、还可以对集合进行交集,并集操作,来查找某些元素的共同点
5)有序集合(Zset)可以使用范围查找,排行榜功能或者topN功能。
Redis的Zset底层实现? redis zset底层实现原理
1)双向链表(ziplist):元素数量小于128个且所有member的长度都小于64字节时使用
2)跳表(skiplist):随机化的多层跳跃链表,每个元素插入时有25%概率从第一层往上加
3)跳表与平衡树和哈希表的比较
a、适合范围查找。哈希表不是有序,不适合范围查找,平衡树范围查找操作复杂
b、内存占用取决于概率p,当为25%时小于平衡树
c、实现比较简单,并且时间复杂度为O(logn)和平衡树一样
Redis地理信息分析 Redis地理算法GEO解析和应用
Redis持久化 redis 通过aof日志恢复_Redis 持久化的这些细节,你真废了吗
1)RDB(Redis DataBase)快照式全量复制
a、手动触发:save:阻塞复制直到完成
bgsave:Redis进程执行fork操作创建子进程,RDB持久化过程有子进程负责,阻塞只发生在fork阶段
b、自动触发:定时持久化命令save m n、子节点全量复制、debug reload命令、shutdown命令
优点:只有一个文件,容量小,转移简单,适用灾难备份,恢复速度快
缺点:定时持久化,无法实时持久,最后一次备份之后的数据丢失
当内存数据集较大时,备份时间较长达到秒级
2)AOF(Append Only File)需手动开启,增量复制,所有命令进行追加
a、关系数据库的写前日志(Write Ahead Log, WAL),先写日志,后写数据,日志中的内容是数据
b、AOF日志是写后日志,先写数据,再写日志,
日志中的内容是操作,先执行保证成功,节省检查命令时间
c、AOF 重写(rewrite)
优点:安全,由于增量,宕机不会破坏之前记录,写入一半崩溃也可以恢复,有写回策略
重写机制控制大小,可以通过移除flushall命令恢复误操作之前的状态
缺点:文件大,恢复慢
Redis默认使用混合持久化
AOF写回策略:AOF持久化写入到缓冲区,再写入到磁盘,可能会丢失数据吗?
三种写回策略 | AOF 耐久性
1)appendfsync always,同步写回:每个写命令执行完,慢但是安全
2)appendfsync everysec,每秒写回:性能适中 宕机时丢失1秒内的数据
3)appendfsync no,是30 秒进行一次 fsync,将缓冲区中的数据写到磁盘上,性能好,宕机时丢失数据较多
Redis线程模型 彻底搞懂Redis的线程模型
Redis事务和乐观锁watch? Redis不具有事务的原子性,因为不能回滚 Redis事务介绍
Redis过期键如何设置?redis key 过期时间如何设置
EXPIRE key 100:设置了过期时间,100秒后,key将自动被删除。
Redis的过期键删除策略? Redis详解:Redis过期键删除策略
1)定时删除:
在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作
缺点:对CPU时间是最不友好的,在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间
2)惰性删除:
放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键
优点:惰性删除策略对CPU时间来说是最友好的:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的键,这个策略不会再删除其他无关的过期键上花费任何CPU时间
缺点:对内存是最不友好的:如果一个键已经过期,而这个键又仍然保留在数据库中,它所占用的内存就不会释放
3)定期删除:
每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多个过期键,以及要检查多少个数据库,则由算法决定
定时删除的定时底层是怎么实现的? Redis 定时处理机制实现流程
Redis定时器实现原理
1.一个循环体循环检查一个链表
2.链表中的节点主要包含时间戳,回调函数
3.每次循环获取当前系统时间,并与链表节点的时间戳对比
4.如果差值大于时间阈值,则执行链表节点的回调函数,并用当前系统时间更新链表节点的时间戳,然后进入下次循环
Redis的内存淘汰机制?Redis 内存淘汰策略 (史上最全)
1)no-envicition:
该策略对于写请求不再提供服务,会直接返回错误,当然排除del等特殊操作,redis默认是no-envicition策略。
2)allkeys-random:
从redis中随机选取key进行淘汰
3)allkeys-lru:
使用LRU(Least Recently Used,最近最少使用)算法,从redis中选取使用最少的key进行淘汰
4)allkeys-lfu:
使用LFU(Least Frequently Used,最不经常使用),从所有的键中选择某段时间之内使用频次最少的键值对清除
5)volatile-ttl:
从redis中选取即将过期的key,进行淘汰
6)volatile-random:
从redis中设置过过期时间的key,进行随机淘汰
7)volatile-lru:
使用LRU(Least Recently Used,最近最少使用)算法,从redis中设置过过期时间的key中,选取最少使用的进行淘汰
8)volatile-lfu:
使用LFU(Least Frequently Used,最不经常使用),从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉
Redis的内存用完了会发生什么? Redis的内存用完了会发生什么?
Redis 的默认回收策略是 noenviction,当内存用完之后,写数据会报错。
MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?(Redis默认没有设置最大内存) MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
同样是在redis.conf配置文件中,可以对最大内存进行设置,单位为bytes:当使用的内存到达指定的限制时,Redis会根据内存淘汰策略删除键,以释放空间。
Redis高可用方案?这可能是目前最全的Redis高可用技术解决方案、Redis的三种集群方式讲解+Redis-Cluster集群搭建
1)Redis单副本
Redis 单副本,采用单个Redis节点部署架构,适用于数据可靠性要求不高的纯缓存业务场景。
优点:
a、架构简单,部署方便。
b、高性价比:缓存使用时无需备用节点(单实例可用性可以用supervisor或crontab保证),当然为了满足业务的高可用性,也可以牺牲一个备用节点,但同一时刻只有一个实例对外提供服务。
缺点:
a、没有备用节点实时同步数据,不提供数据持久化和备份策略,不保证数据的可靠性。
b、在缓存使用,进程重启后,数据丢失,即使有备用的节点解决高性能,但是仍然不能解决缓存预热问题。
c、受限于单核CPU的处理能力(Redis是单线程机制),所以适合操作命令简单,排序,计算较少的场景。
2)Redis多副本(主从)
Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。
优点:
a、高可靠性:能够在主库出现故障时自动进行主备切换,从库提升为主库提供服务,保证服务平稳运行
b、开启数据持久化功能和配置合理的备份策略,能有效的解决数据误操作和数据异常丢失的问题。
c、读写分离策略:从节点可以扩展主库节点的读能力,有效应对大并发量的读操作。
缺点:
a、故障恢复复杂,当主库节点出现故障时,需要手动将一个从节点晋升为主节点
b、主库的写能力和存储能力受到单机的限制。
c、主库执行全量备份的同时,可能会造成毫秒或秒级的卡顿。
3)Redis Sentinel(哨兵)
部署架构主要包括Redis Sentinel 集群和 Redis 集群,其中Redis Sentinel 集群是由若干Sentinel 节点组成,可以实现故障发现,故障自动转移,配置中心和客户端通知。Sentinel 的节点数量要满足 2n + 1 奇数个。
优点:
a、能够解决 Redis 主从模式下的高可用切换问题
b、方便实现 Redis 数据节点的线形扩展,极大满足 Redis 大容量或高性能的业务需求
c、可以实现一套 Sentinel 监控一组 Redis 数据节点或多组数据节点。
缺点:
a、部署相对 Redis 主从模式要复杂一些
b、资源浪费,Redis 数据节点中 slave 节点作为备份节点不提供服务;
c、不能解决读写分离问题,实现起来相对复杂
4)Redis Cluster(集群)
Redis Cluster 集群节点最小配置 6 个节点以上(3 主 3 从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。Redis Cluster 采用虚拟槽分区,所有的键根据哈希函数映射到 0~16383 个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据。
优点:
a、无中心架构,数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;
b、可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除
c、高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升;
d、降低运维成本,提高系统的扩展性和可用性。
缺点:
a、Client 实现复杂,数据通过异步复制,不保证数据的强一致性
b、多个业务使用同一套集群时,无法根据统计区分冷热数据,资源隔离性较差,容易出现相互影响的情况。
c、Slave 在集群中充当“冷备”,不能缓解读压力
Redis集群选举机制?redis集群选举机制、redis集群与哨兵选举原理
1)Redis哨兵中的选举机制
a、故障节点主观下线
Sentinel集群的每一个Sentinel节点会定时对redis集群的所有节点发心跳包检测节点是否正常。如果一个节点在down-after-milliseconds时间内没有回复Sentinel节点的心跳包,则该redis节点被该Sentinel节点主观下线。
b、故障节点客观下线
主观下线并不意味着该节点肯定故障了,如果Sentinel集群中超过quorum数量的Sentinel节点认为该redis节点主观下线,则该redis客观下线。如果客观下线的redis节点是从节点或者是Sentinel节点,则操作到此为止;如果客观下线的redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。
c、Sentinel集群选举Leader
当一个Sentinel节点确认主节点主观下线后,会请求其他Sentinel节点要求将自己选举为Leader。被请求的节点如果没有同意过其他选举请求,则同意该请求(选举票数+1)。如果一个Sentinel节点获得的选举票数达到Leader最低票数(quorum和Sentinel节点数/2+1的最大值),则该Sentinel节点选举为Leader;否则重新进行选举。
d、Sentinel Leader决定新主节点
Sentinel Leader从redis从节点中选择一个redis节点作为主节点,过滤故障的节点选择优先级slave-priority最大的从节点作为主节点。
2)Redis集群中的选举机制
a、当slave发现自己的master挂了,将自己记录的currentEpoch加1,并向其他节点请求投票给自己成为master
b、其他节点收到请求,只有master会回应并投票,可能会有多个slave请求,每个master只能投一票
c、slave收集master的投票,当slave收到的投票超过半数后就可以成为master,并广播消息通知其他节点
Redis集群哈希槽 Redis哈希槽,对于哈希槽的理解,以及高并发情况下哈希槽不够的情况讲解,热点缓存的解决思路、Redis - Redis 哈希槽的概念
一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
渐进式Rehash查找细节 渐进式哈希总结
1)步骤
在 rehash 进行期间, 每次对字典执行添加、删除、查找或者更新操作时, 程序除了执行指定的操作以外, 还会顺带将 ht[0] 哈希表在 rehashidx 索引上的所有键值对 rehash 到 ht[1] , 当 rehash 工作完成之后, 程序将 rehashidx 属性的值增一。
2)增删改查
增加只增加在新哈希表,新插入的键值对会放在链表的头部,而不是在尾部继续插入,头插法的时间复杂度为O(1),并且最新插入的数据往往更可能频繁地被获取
查找一个key的话,会先在ht[0]里面进行查找,如果没有找到的话,就会继续到ht[1]里面进行查找。
删除和修改都在两个表进行
分布式面试问题 面试题汇总-分布式(一)
CAP和Base理论 分布式之CAP原则详解
1)一致性(Consistency):在分布式系统中的所有数据备份,在同一时刻是否同样的值,即写操作之后的读操作,必须返回该值。(分为弱一致性、强一致性和最终一致性)
2)可用性(Availability):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
3)分区容忍性(Partition tolerance):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
4)解决方案BASE:BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写,BASE是对CAP中一致性和可用性权衡的结果
a、基本可用Basically Available
响应时间稍微增长1-2s,功能上的损失,如引导用户到一个降级页面
b、软状态Soft state
软状态也称弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性
c、最终一致性Eventually consistent
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态
分布式事务,2PC,3PC,TCC? 面试官问我知道的分布式事务,我一口气说了六种、常用的分布式事务解决方案
1)两阶段提交协议 2PC(强一致性)
a、原理
该分布式系统中,存在一个节点作为协调者(Coordinator),其他节点作为参与者(Cohorts)
①、第一阶段(投票阶段)
协调者节点向所有参与者节点询问是否可以执行提交操作(vote)
②、第二阶段(提交执行阶段):
协调者发出正式提交(commit)或回滚操作(rollback)请求。
b、缺点
①、性能问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
②、可靠性问题:
参与者发生故障,协调者需要给每个参与者额外指定超时机制,超时后整个事务失败。(没有多少容错机制)
协调者发生故障,参与者会一直阻塞下去。需要额外的备机进行容错。(这个可以依赖后面要讲的Paxos协议实现HA)
④、数据不一致问题:协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
2)三阶段提交协议 3PC
a、改动
与两阶段提交不同的是,三阶段提交有两个改动点:
①、引入超时机制。同时在协调者和参与者中都引入超时机制。增加了参与者的超时,协调者挂了不会阻塞等,参与者可以直接提交,但这样会导致数据不一致。
②、在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。3PC 的引入是为了解决提交阶段 2PC 协调者和某参与者都挂了之后新选举的协调者不知道当前应该提交还是回滚的问题。多了一个阶段知道统一是提交还是回滚的状态。但是挂了的参与者到底执行没执行还是无法解决。
b、原理
①、准备CanCommit阶段
和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
②、预提交PreCommit阶段
假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。
假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断
③、提交DoCommit阶段
该阶段进行真正的事务提交,包含两种情况,执行提交和提交中断
3)补偿事务 TCC
a、原理
TCC 指的是Try - Confirm - Cancel
①、Try 指的是预留,即资源的预留和锁定, 注意是预留。
②、Confirm 指的是确认操作,这一步其实就是真正的执行了。
③、Cancel 指的是撤销操作,可以理解为把预留阶段的动作撤销了。
b、特点
TCC难点在于业务上的定义,对于每一个操作你都需要定义三个动作分别对应Try - Confirm - Cancel,因此 TCC 对业务的侵入较大和业务紧耦合,需要根据特定的场景和业务逻辑来设计相应的操作。撤销和确认操作的执行可能需要重试,因此还需要保证操作的幂等。
c、区别
2PC 和 3PC 都是数据库层面的,而 TCC 是业务层面的分布式事务
RAFT算法 RAFT算法详解
ZAB协议原理? Zab协议详解
Zookeeper ZooKeeper面试题(2020最新版)
分布式锁 分布式锁看这篇就够了、面试问题:有没有用过分布式锁,怎么实现的
高并发、高性能、高可用 后台高并发、高性能的常见解决方式
秒杀系统的架构设计 面试了十个应届生九个都是秒杀系统,你确定你们那是秒杀?
高并发系统的缓存、降级和限流。限流怎么做 高并发系统如何做到限流,看这篇就对了!
如何生成唯一ID?分布式id生成器怎么实现? 分布式「唯一ID生成器」的几种生成方案
1)UUID
a、机器的网卡 + 当地时间 + 一个随记数 => UUID
b、优点:本地生成,生成简单,性能好,没有高可用风险
c、缺点:长度过长,存储冗余,且无序不可读,查询效率低
2)数据库Id自增策略
a、定义:使用数据库的id自增策略,如 MySQL 的 auto_increment
b、高可用:使用两台数据库分别设置不同步长,生成不重复ID的策略来实现高可用。
c、优点:数据库生成的ID绝对有序,高可用实现方式简单
d、缺点:需要独立部署数据库实例,成本高,有性能瓶颈
3)Redis生成ID
a、定义:Redis的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的。
b、高可用:使用 Redis 集群来获取更高的吞吐量。假如一个集群中有5台 Redis。可以初始化每台 Redis 的值分别是1, 2, 3, 4, 5,然后步长都是 5。
c、优点:不依赖于数据库灵活方便,性能优于数据库;数字ID天然排序,对分页或者需要排序结果很有帮助。
d、缺点:如果系统中没有Redis,还需要引入新的组件,增加系统复杂度;需要编码和配置的工作量比较大
4)雪花算法(twitter 的 snowflake算法)
负载是什么,负载和CPU,负载均衡策略?
Memcached、Ningx、Nacos 服务注册中心、Ribbon 负载均衡
RPC协议(动态代理,封装调用细节,序列化与反序列化,数据传输与接收,通信,异常处理) RPC介绍与原理
WARO协议和Quorum机制 分布式系统原理 之4 Quorum 机制
幂等是什么?跨库的幂等如何解决?(虾皮提前批一面)微服务:幂等机制和解决方案、高并发下接口幂等性解决方案
Get、Put、Delete方法是幂等的
消息中间件 消息中间件MQ与RabbitMQ面试题(2020最新版)、字节跳动面试官这样问消息队列:分布式事务、重复消费、顺序消费,我整理了一下、面试官问我:什么是消息队列?什么场景需要他?用了会出现什么问题?
一致性哈希 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)
Hash算法让固定的一部分请求落到同一台服务器上,起到负载均衡的作用。但是普通的余数hash(hash(比如用户id)%服务器机器数)算法伸缩性很差,当新增或者下线服务器机器时候,用户id与服务器的映射关系会大量失效。一致性hash则利用hash环对其进行了改进。