项目常见面试问题
![](https://img2023.cnblogs.com/blog/1368961/202302/1368961-20230222124149806-1022171705.png)
项目常见面试问题
一、你的项目中缓存粒度是如何选择的?
缓存粒度一共分为4种. 1.缓存某个数值:一个键只保存一个值,性价比较低,使用率低,如果存储的话我们使用redis的String 2.缓存数据对象:数据库记录对应的具体数据,优点是可以多次复用,String,hash 3.缓存数据集合:数据库查询对应的结果集,可以和数据对象配合使用,方便数据对象的重用,hash,list,set,zset,String(zset,String) 4.缓存试图响应:试图返回的相应数据,复用性比较差,String 所以我们项目中主要对数据集合+数据对象进行缓存,他们的优点是复用性强,节省内存空间.
二、使用过redis的那些格式做过缓存,其他应用场景和优缺点是什么?
包括list,zset,set,hash和json字符串 其中我们使用过json字符串和zset set用来存放无序去重的数据, 如果有判断是否存在的需求 zset有排序的需要list,如果说是按时间查询, 查询的结果固定, 不需要分页的情况下,我们使用list因为查询的比较快 但如果有额外排序要求, 而且需要分页, 我们使用zset(查询时间跟查询的长度和数据量有关,跟查询区别无关, 查询速度比较均衡), 增加数据效率和存储的数据量负相关,数据量越大,添加时间越长,查询数据效率和存储的数据量负相关,并且和查询的结果集数据量有关 json字符串需要进行转换,使用pickle模块提高性能,无法单独更新某个字段,节省空间
三、生产环境下缓存数据redis满了怎么办,如何在不停止服务器的前提下扩容?
我们通过Redis的Cluster集群来实现扩展存储空间,在不停掉Cluster集群环境的情况下通过redis-trib.rb脚本文件来动态的往集群环境中增加主,从节点,也可以动态的从集群环境中删除节点 配置连接https://www.cnblogs.com/PatrickLiu/p/8473135.html 1. 创建两个redis实例, 修改配置文件ip和端口号 2. 把创建的两个实例添加到cluster集群中# ruby redis-trib.rb add-node 192.168.127.130:7006 192.168.127.130:7000 3. cluster nodes 进行验证节点 , (默认都是主master) 4. 从主节点master上抽取一些slots分给要加入的这个主节点 # ruby redis-trib.rb reshard 192.168.127.130:7000 5. 选择接收数据槽的节点和数据槽产生的方式 选择all 6. 执行分配计划 yes_ 7. 增加这从节点7007到集群中 # ruby redis-trib.rb add-node 192.168.127.130:7007 192.168.127.130:7000 8. 将从7007节点作为主节点的从节点实现主从配置 进入 7007redis 执行> cluster replicate 71ecd970838e9b400a2a6a15cd30a94ab96203bf(这里是主节点的ID) 首先把redis的 maxmemory 调到最大, 然后把这个maxmemory-policy调成LFU淘汰策略 使用过期策略和缓存淘汰机制 过期策略中选择惰性过期+定期过期(每100ms对设置了过期时间的数据随机查询并删除过期数据) 缓存淘汰中有LFU和LRU.LFU:优先淘汰不是频繁使用的数据,有定期衰减这个机制,由于消费较高, 所以我们基本会选择LRU:优先淘汰不是最近使用的数据.淘汰策略maxmemory-policy volatile-lru
四、缓存穿透和缓存雪崩是什么,如何解决?
缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,
如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存. 解决办法:1.对于数据库中不存在的数据,也对其在缓存中设置默认值一般过期时间会比较短 2.可以设置一些过滤规则, 如布隆过滤器(算法, 用于判断数据是否包含在集合中), 将所有可能的值录入过滤器, 如果不包含直接返回None, 有误杀概率 缓存雪崩,是指在某一个时间段,缓存集中过期失效。 1.设置过期时间时,添加随机值,让过期时间进行一定程度分散 2.多级缓存的方式来处理 3.利用锁/队列的形式
五、项目中使用的缓存模式是什么,遇到过哪些问题?
1.Cache Aside 更新模式(同时更新缓存和数据库) 更新丢失(先更新数据库,后删除缓存), 缓存穿透, 缓存雪崩 2.Read/Write Through 更新模式(通读通写) 应用程序只需要维护缓存,数据库的维护工作由缓存代理 read through : 在查询操作中更新缓存,也就是说,当缓存失效的时候,Cache Aside 模式是由调用方负责把数据加载入缓存,而 Read Through 则用缓存服务自己来加载。 write through: 和 Read Through 相仿,不过是在更新数据时发生。当有数据更新的时候,如果没有命中缓存,直接更新数据库,然后返回。
如果命中了缓存,则更新缓存,然后由缓存自己更新数据库(这是一个同步操作) 3.Write Behind Caching 更新模式 就是在更新数据的时候,只更新缓存,不更新数据库,而我们的缓存会异步地批量更新数据库,这个设计的好处就是直接操作内存速度快。 因为异步,Write Behind Caching 更新模式还可以合并对同一个数据的多次操作到数据库,所以性能的提高是相当可观的。
但其带来的问题是,数据不是强一致性的,而且可能会丢失。另外,Write Behind Caching 更新模式实现逻辑比较复杂,因为它需要确认有哪些数据是被更新了的,哪些数据需要刷到持久层上。
只有在缓存需要失效的时候,才会把它真正持久起来。
六、读写分离对事务是否有影响?
对于写操作包括开启事务和提交或回滚要在一台机器上执行,分散到多台master执行后数据库原生的单机事务就失效了。 对于事务中同时包含读写操作,与事务隔离级别设置有关,如果事务隔离级别为read-uncommitted 或者 read-committed,读写分离没影响,
如果隔离级别为repeatable-read、serializable,读写分离就有影响,因为在slave上会看到新数据,而正在事务中的master看不到新数据。
七、varchar和char的区别,utf8字符集下varchar最多能存多少个字符 ?
char的长度不可变,查询效率高,可能造成存储浪费,用于手机号.varchar长度可变,,查询效率低,节省空间,用于用户名.在UTF8字符集下最大长度不能超过21845
八、primary key和unique的区别?
unique可空,可以在一个表里的一个或多个字段定义; primary key不可空不可重复,在一个表里可以定义联合主键.
九、什么是外键约束?
不使用SQL建立外键, 而是定义普通的键去记录主键(逻辑外键) 仍然可以多表联查,删除和更新效率高,但是会有出错的风险,有程序逻辑来控制.
十、什么是索引?
为了提高查询速度提供的一种数据结构, 类似书的目录, 方便快速查询出数据, 而不是从头到尾的依次对比,优点:增加查询速度,缺点:增加数据库的存储空间,减慢增删改速度
十一、索引的分类?
普通索引index:不要用可空列作为索引, 易出错. 适合数据量超过300的表,经常与其他表进行连接的表,经常出现在Where子句中的字段,选择性高的字段和小字段.频繁进行数据操作的表,不要建立太多的索引;适用于改动小,查询多的场景. 联合索引:联合索引必须符合最左原则, 否则无效. 主键索引:创建主键后自动生成 唯一索引:设置唯一约束后自动生成 外键索引:设置外键约束后自动生成
十二、索引的原理
Mysql的索引存储结构为B+tree结构 平衡二叉树. 聚簇索引: 主键B+树在叶子节点直接存储的是数据行, InnoDB引擎使用. 优点: 主键查询的速度非常快 缺点: 增删改比较慢,其它的主键查询要二次查询 非聚簇索引: 主键B+树在叶子节点只是存储真正数据行的地址, 数据行和索引存储在不同的结构中,MyISAM引擎使用 优点: 增删改比较快, 非主键的查询也比较快 缺点: 不支持事务
十三、InnoDB的主键为什么选择自增 ?
数据和主键索引是绑定在一起的, 主键自增就会让数据顺序添加到B+Tree中, 写完一页再写下一页, 不需要为了索引的排列而移动数据和页分裂, 并且移动和页分裂也会降低查询速度
十四、能不能使用业务字段作为主键(业务主键) ?
可以, 但不好 使用自增主键性能会快很多 业务字段更新频繁,一旦修改,索引也要跟着变,成本较高 所以一般采用和业务无关的数据充当主键(逻辑主键)
十五、联合主键
将多个业务键联合定义为主键 优点:节省空间 缺点:和业务有关, 频繁改动,不是自增,性能差,尽量不要用
十六、三范式和反范式设计
第一范式: 字段具有原子性, 不可拆分 第二范式: 依赖于全部主键, 而非部分主键 第三范式: 只依赖于主键, 非主键字段互不依赖 目的是减少冗余字段 如果单独定义字段来记录,该字段就称为冗余字段,这种设计称为反范式设计. 通过加入冗余字段,来提高数据库的查询速度,减少关联查询,用空间换取时间 范式是武功招式, 如何运用全看自己, 也有缺点, 查询速度高了,会增加很多写入操作
十七、分库分表前后的问题?
分表分库前的问题, 用户请求量太大,解决办法:分散请求到多个服务器上 单库太大,解决方法:切分成更多更小的库 单表太大,解决方法:切分成多个数据集更小的表 分表分库后的问题, 事务支持,分表分库后,就成了分布式事务 多库结果集合并 跨库join
十八、mysql锁
它的目的是解决并发情况下资源抢夺问题, 维护数据的一致性, mysql的锁虽然开发者可以手动设置, 但比较影响并发性, 一般会使用乐观锁代替,由于mysql会自动使用锁, 所以需要了解锁机制, 以便优化数据库并发能力. 分为行级锁和表级锁. 行级锁:对数据行锁定, 并发好, 资源消耗多 表级锁:对整个表锁定, 并发差, 资源消耗少
十九、锁和事务,锁和事务的优化建议
无论操作是否在事务中, 都可以获取锁, 只不过在事务中, 获取的锁只有执行完事务才会释放 优化建议: 1.使用读取已提交事务隔离级别 2.精心设计索引 3.选择合理的事务大小 4.最好一次性请求足够级别的锁 5.约定以相同的顺序访问各表 6.用相等条件访问数据 7.除非必须,查询时不要显式加锁
二十、行锁与读写权限
行共享锁:获取行共享锁后, 当前事务可以读,不一定能写;其他事务可以读,不能写. 共享锁容易出现死锁陷阱 行排他锁:获取后,当前事务既可以读,也可以写;其他事务可以读,不能写 行锁是通过给索引加锁实现的,如果查询时没有触发索引,就会锁表,使用读取已提交事务隔离级别,只锁行,不锁表
二十一、什么是间隙锁
对于键值在条件范围内但并不存在的记录,叫做'间隙' 在击中索引的情况下,获取行锁时,InnoDB不仅会对符合条件的已有数据行加锁,也会对这个'间隙'加锁 InnoDB完整的行锁机制为 下键锁 缺点是会阻塞符合条件的插入操作,目的是防止幻读. 解决办法:1.尽量不要对有频繁插入的表进行范围条件的检索 2.使用读取已提交事务隔离级别 3.使用唯一索引或主键索引进行查询
二十二、mysql事务和事务隔离级别
目的: 保证数据库安全稳定运行的技术 四大特性: ACID 原子性 一致性 隔离性 持久性 原子性: 要么都成功, 要么都失败,实现机制是undo log 一致性:操作前后, 系统稳定, 数据一致,原子性不代表一致性: 脏读/不可重复读/幻读: 解决办法:调整事务级别 提交事务后, 只有一半操作持久化成功: 解决办法: redo log 隔离性:每个事务是独立的,相互不会影响,实现机制多版本并发控制+锁(MVCC+锁) 持久性:保证事务的执行结果一定能在数据库中同步完成, 无论数据库所在硬件是否瘫痪,实现机制: redo log 原子性 持久性 隔离性 实现了一致性 事务隔离级别:四个级别, 只会用到读已提交和可重复读这两个 mysql默认为可重复读,更建议使用读取已提交,不会加间隙锁,索引没触发,不会锁表,只是锁行,不可重复读和幻读问题, 一般不需要管, 如果有强制要求, 加悲观锁/乐观锁
二十三、MVCC多版本并发控制
简单来说就是对数据做了多版本控制,事务隔离级别中的RC和RR就是MVCC实现的 RR可重复读级别: 快照读: select * from xx: # 在事务中无论读多少次都和第一次读的结果一样 当前读: select * from xx lock in share mode; select * from xx for update和insert update delete 语句 RC读取已提交级别: 仍然有快照读, 事务提交成功的数据可以读取得到, 但读不到未提交的数据
二十四、MyISAM 和InnoDB
MyISAM:只支持表级锁 表读锁/共享锁:获取后, 其他请求可以读不能写,对MyISAM的读操作,不会阻塞其他用户对同一表读请求,但会阻塞对同一表的写请求; 表写锁/排它锁:获取后, 其他请求既不能读也不能写,对MyISAM的写操作,则会阻塞其他用户对同一表的读和写操作; 加锁方式:1.数据库自动管理,查询前给设计的表添加读锁, 更新前(增删改)给涉及的表加写锁 2.MyISAM在执行查询语句前,会自动给涉及的所有表加共享锁,一旦上共享锁,其他进程就不能获取排它锁, 就不能进行写操作, 在执行更新、删除、增加操作前,会自动给涉及的表加写锁,这个过程并不需要用户干预 3.MyISAM表的读操作和写操作之间,以及写操作之间是串行的。 4.当一个线程获得对一个表的写锁后,只有持有锁线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。 InnoDB:支持行级锁和表级锁, 优先使用行级锁 行共享锁:获取后, 其他事务也可以获取目标集的共享锁, 但不能获取目标集的排他锁 行排它锁:获取后, 其他事务既不能获取目标集的共享锁, 也不能获取对应的排它锁 加锁方式:1.对于查询语句,innodb不会加任何锁,也就是可以多个并发去进行查询的操作,不会有任何的锁冲突,因为根本没有锁。 2.对于增加、删除、更新操作,innodb会自动给涉及到的数据加排他锁,只有查询操作需要我们手动设置排他锁。 3.执行增删改前自动加排它锁 4.查询语句不需要任何锁, innoDB也不添加任何锁 5.增删改必须获取排它锁, 普通查询不需要获取任何锁
二十五、REDO和UNDO
UNDO:作用:1.用于回滚,现实事务的原子性 2.实现多版本并发控制(MVCC) 原理:在数据操作只从之前,先将牵扯到的数据备份到UNDO LOG, 然后再进行数据的操作 如果出现回滚操作,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态 Undo log必须先于数据持久化到磁盘,如果在D,E之间系统崩溃, undo log是完整的,可以用来回滚事务 REDO:记录的是新数据的备份 作用:保证事务持久性 原理:1 新数据写入内存缓冲区后,将执行的更新操作写入redo log,再将数据写入磁盘(一定发生在redo写入之后,但未必立即执行) 2.当系统崩溃时,虽然数据没有写入磁盘,但是Redo Log已经持久化,系统可以根据Redo log的内容,将所有数据恢复到最新的状态 3.虽然redo log和写入数据库 都是写入磁盘,但是redo log的性能高于写入数据库(redo log只写入命令,不添加事务的判断) 数据库恢复:1.mysql重启后自动进行 2.先REDO,再UNDO 3.进行恢复时, 3.1 REDO不区分事务,会重复做所有操作(包括未提交的操作和最终回滚的操作) 3.2 然后再由UNDO来回滚未提交和要执行回滚的事务
二十六、数据库引擎
实现数据存储的不同解决方案 InnoDB mysql5.5开始 默认 支持事务,支持行级锁和表级锁,并发访问时效率高,支持外键约束,插入/更新/主键查询快,需要内存和硬盘多,常规推荐使用 MyISAM:不支持事务,不支持外键约束,只支持表级锁,批量插入/查询/count速度快 简单, 适合小型项目和以批量插入和查询为主的系统(内部管理系统)
二十七、什么是RPC,gRPC?
RPC (远程过程调同) 是一个计算机通信协议 作用: 可以以函数形式来调用另一台计算机上的程序 优点: 使用自定义的二进制形式进行数据传输, 效率极高 应用场景:子系统之间进行数据交互 grpc:谷歌开发的高性能的RPC框架 优点:1.使用http2.0标准, 支持双向流和多路复用 2.支持多语言和多平台 http2.0利用二进制的分帧层对请求头,请求体进行分组分包, 这样就允许在同一个连接可以发送和接收多个请求的数据 主要特点:二进制分帧层,多路复用,头部压缩,服务器推送
二十八、APSchedule定时器
分为crontab和apschedule crontab:是linux系统一个内置命令,依赖于linux系统,无动态管理任务,适合于普通的静态任务. apschedule:独里的定时器程序,可以方便的管理定时任务,需要动态生成. 支持三种触发器 date 只执行一次 interval 周期执行 参数时间间隔 cron 周期执行 参数时间
二十九、缓存更新问题
mysql和redis是两个独立的系统,在并发环境下,无法保证更新的一致性,解决办法:更新数据时,先写入mysql,再删除缓存,设计分布式锁或使消息队列串行处理
三十、缓存有效期和淘汰策略
设置有效期的作用:1.节省空间 2.做到数据弱一致性,有效期失效后,可以保证数据的一致性 过期策略:1.定时过期:效率太低,每个数据都需要设置定时器进行计数 2.惰性过期:查询时,才去检查数据的有效期,如果过期,则返回nil,并删除过期数据 3.定期过期:每隔100ms,随机取出一部分数据进行过期校验,如果过期, 删除数据 redis中选择惰性过期+定期过期 (每100ms对设置了过期时间的数据随机查询并删除过期数据) LRU:least recently use 优先淘汰不是最近使用的数据 LFU:least frequently use 优先淘汰不是频繁使用的数据 采用了定期衰减的机制, 防止旧数据始终无法删除 缺点:需要每条数据维护一个使用计数,还需要定期衰减
三十一、为什么不用定时过期策略?
定时过期,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.
三十二、定期过期+惰性过期是如何工作的呢?
定期过期,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,
而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期过去策略,会导致很多key到时间没有删除。 于是,惰性过期派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。
三十三、采用定期过期+惰性过期就没其他问题了么?
不是的,如果定期过期没删除key。然后你也没即时去请求key,也就是说惰性过期也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。
三十四、JWE
对称加密: 代表算法 des 3des aes,速度快 非对称加密: 代表算范 rsa 速度慢,不适合大型数据加密 加密时,一般公钥加密,私钥解密,与签名相反 私钥唯一,使用私钥签名,公钥验签,可以保证签名者身份唯一 主要用于数据加密 最佳方案 (JWE) 传输的数据使用对称加密, 生成数据密文, 对称加密秘钥是随机的,为了防止数据篡改,对数据密文进行摘要认证,摘要认证的秘钥也是随机的,对称加密的秘钥和摘要认证的秘钥使用非对称加密进行处理 JWE的耗时远高于JWS
三十五、为什么使用JWT进行状态保持?
因为APP不支持状态保持,状态保持有同源策略,无法跨服务器传递,所以不采用session.session依赖于cookie不安全,session存在于数据库,用户多时,影响数据库性能
三十六、什么是JWT?
JWT不可逆加密部分主要用于数据认证, 防止数据被修改
三十七、CDN加速是对网站所在服务器加速,还是对其域名加速?
CDN是只对网站的某一个具体的域名加速。如果同一个网站有多个域名,则访客访问加入CDN的域名获得加速效果,访问未加入CDN的域名,或者直接访问IP地址,则无法获得CDN效果。 三十八、CDN使用后,原来的网站是否需要做修改,做什么修改? 一般而言,网站无需任何修改即可使用CDN获得加速效果。只是对需要判断访客IP程序,才需要做少量修改。
三十九、如何解决刷新问题?
1.手机号+验证码(或帐号+密码)验证后颁发接口调用token与refresh_token(刷新token) 2.Token 有效期为2小时,在调用接口时携带,每2小时刷新一次 3.提供refresh_token,refresh_token 有效期14天 4.在接口调用token过期后凭借refresh_token 获取新token 5.未携带token 、错误的token或接口调用token过期,返回401状态码 6.refresh_token 过期返回403状态码,前端在使用refresh_token请求新token时遇到403状态码则进入用户登录界面从新认证。
四十、判断问题发生在前端还是后端?
如果前端为网页,可以通过网页调试工具里面的network判断 如果前端不是网页,比如app,通过日志的访问请求记录判断 如果是后端出现的问题,通过pycharm或日志来判断
四十一、数据库优化
1.在进行表设计时,可适度增加冗余字段(反范式设计),减少JOIN操作; 2.多字段表可以进行垂直分表优化,多数据表可以进行水平分表优化; 3.选择恰当的数据类型,如整型的选择; 4.对于强调快速读取的操作,可以考虑使用MyISAM数据库引擎; 5.对较频繁的作为查询条件的字段创建索引;唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;更新非常频繁的字段不适合创建索引; 6.编写SQL时使用上面的方式对SQL语句进行优化; 7.使用慢查询工具找出效率低下的SQL语句进行优化; 8.构建缓存,减少数据库磁盘操作; 9.可以考虑结合使用内在型数据库,如Redis,进行混合存储。
四十二、Redis事务
语法: 1.MULTI:开启事务, 后续的命令会被加入到同一个事务中 事务中的操作会发给服务端, 但是不会立即执行, 而是放到了该事务的对应的一个队列中, 服务端返回QUEUED 2.EXEC:执行EXEC后, 事务中的命令才会被执行,事务中的命令出现错误时, 不会回滚也不会停止事务, 而是继续执行 3.DISCARD:取消事务, 事务队列会清空, 客户端退出事务状态 ACID: 1.原子性: 不支持, 不会回滚并且有错误也会继续执行 2.隔离性: 支持, 单进程,单线程, 事务中的命令顺序执行, 并且不会被其他客户端(事务)打断(先EXEC的先执行)在事务中的会一次性执行完再执行下一个命令(事务) 3.持久性:不支持, redis数据丢失 4.一致性: 不支持, 如果强制使用一致性,需要加乐观锁(watch监听) watch:redis实现的乐观锁 可以实现秒杀超卖需求 事务开启前, 设置对数据的监听, EXEC时, 如果发现数据发生过修改, 事务会自动取消 事务EXEC后, 无论成败, 监听会被移除 setnx和悲观锁:setnx键不存在,才会设置成功
四十三、Redis持久化
分为RDB快照存储和AOF只追加文件 RDB:将内存中的所有数据 完整的保存到硬盘中,配置中设置自动持久化策略 优点:方便数据备份:由于保存到单独的文件中,易于数据备份 写时复制:子进程单独完成持久化操作,父进程不参与IO操作, 最大化redis性能 恢复大量数据时,速度优于AOF 缺点:不是实时保存数据,如果redis意外停止工作,则可能会丢失一段时间的数据 数据量大时,fork进程会比较慢,持久化时使redis响应速度变慢 AOF:只追加而不是全部重新写入,追加命令而不是数据 优点:更可靠 默认每秒同步一次操作,最多丢失一秒数据 可以进行文件重写,以避免AOF文件过大 缺点:相同数据集,AOF文件比RDB体积大,恢复速度慢 除非是不同步情况,否则普遍要比RDB速度慢
四十四、如何选择RDB和AOF?
对于更新频繁,一致性要求不是非常高的数据可以选择使用redis进行持久化存储 RDB or AOF: 数据安全性要求高, 都打开 可以接受短时间的数据丢失, 只使用RDB 即使使用AOF,最好也开启RDB,因为便于备份并且回复速度快,bug更少 使用redis进行一部分数据的持久化存储 两种持久化机制都开启
四十五、什么是哨兵机制?
监控redis服务器的运行状态,可以进行自动故障转移,实现高可用,与数据库主从配合使用的机制 特点: 1.独自的进程, 每台redis服务器应该至少配置一个哨兵程序 2.监控redis主服务器的运行状态 3.出现故障后可以向管理员/其他程序发出通知 4.针对故障,可以进行自动转移, 并向客户端提供新的访问地址 至少在3台服务器上分别启动至少一个哨兵 如果只有一台,则服务器宕机后,将无法进行故障迁移 如果只有两台,一旦一个哨兵挂掉了,则投票会失败 心跳机制和投票裁决
四十六、什么是集群?
多个节点共同保存数据,它能扩展存储空间,提高吞吐量,提高写的性能,不在区分数据库,只有0号库,单机默认0-15,不支持事务,管道和多值操作. 要求至少三主三从,要求必须开启AOF持久化,自动选择集群节点进行存储,默认集成哨兵,自动故障转移 redis集群不能支持事务和WATCH, 并发控制只能自己设计悲观锁,集群负责实现缓存设计
四十六、数据库设计?
索引的原理采用了B+Tree平衡二叉树结构,有聚簇索引和非聚簇索引,
聚簇索引:主键B+树在叶子节点直接存储的是数据行, InnoDB引擎使用.优点: 主键查询的速度非常快,缺点: 增删改比较慢,其它的主键查询要二次查询
非聚簇索引:主键B+树在叶子节点只是存储真正数据行的地址, 数据行和索引存储在不同的结构中,MyISAM引擎使用优点: 增删改比较快, 非主键的查询也比较快
缺点: 不支持事务
所以我们大多数的表都使用了聚簇索引和InnoDB引擎,因为InnoDB引擎支持事务,可以进行事务回滚,恢复速度快,还支持行级锁和表级锁,
提高并发访问时的效率,支持外键约束,插入更新主键查询快,但是需要的内存和硬盘多,
而MyISAM引擎不支持事务和外键约束,只支持表级锁,批量插入和查询速度快,适合小型项目,我们项目中系统公告表因为基本不会修改,
不存在大量并发写操作,也就不需要行级锁和事务为数据安全稳定做保障,查询多,MyISAM的查询速度会更快.
当初我们尝试使用业务字段作为主键,结果是可以使用,但是不太好,业务字段更新频繁,一旦修改,索引也要跟着变,成本比较高,所以我们采用和业务无关的数据充当主键.