一、你的项目中缓存粒度是如何选择的?

缓存粒度一共分为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的查询速度会更快.
当初我们尝试使用业务字段作为主键,结果是可以使用,但是不太好,业务字段更新频繁,一旦修改,索引也要跟着变,成本比较高,所以我们采用和业务无关的数据充当主键.

最新文章

  1. Effective Java 67 Avoid excessive synchronization
  2. oracle中修改表名
  3. Why java main function is declared as static type?
  4. Ehcache(06)——监听器
  5. javascript小实例,PC网页里的拖拽(转)
  6. hdu 4497 GCD and LCM
  7. ibatis缓存初探(1)
  8. shell修改文件名(二)
  9. autoSvn
  10. oracle数据表误删恢复
  11. SVG-1
  12. HDU 5781 ATM Mechine
  13. New Adventure----GUI Design Studio
  14. [原创]CentOS下Mysql的日志回滚
  15. Linux下串口通信工具minicom的用法
  16. Redis集群的相关概念
  17. 5、C#基础 - C#的值类型
  18. thinkphp5URL和路由
  19. Enterprise architect 类图加时序图
  20. Elasticsearch Query DSL

热门文章

  1. Linux运维工程师成长路线及应实现的目标
  2. 逆向工程mybatis-geneator.xml
  3. 剖析Qt的事件机制原理(源代码级别)
  4. qobject_cast<QPushButton*>(sender()) 简化信号与槽的编写(sender()取得发信号的对象后,就取得了它的全部信息,为所欲为)
  5. windows 消息列表
  6. Python基础(六) 函数
  7. SYN2306B型 GPS北斗双模授时板
  8. 戏说 .NET GDI+系列学习教程(一、Graphics类--纸)
  9. Java 位域
  10. Python 3.6 安装