数据库

Mysql事务日志undolog和redolog

https://www.cnblogs.com/f-ck-need-u/p/9010872.html
undo log有两个作用:提供回滚和多个行版本控制(MVCC)。如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。有时候应用到行版本控制的时候,也是通过undo log来实现的:当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

redolog用于重做,是物理日志,记录数据页的物理修改,用于恢复到最后一次提交的物理数据页。

     LSN:LOG SEQUENCE NUMBER 日志序列号 ,redolog、数据页、checkpoint都有LSN,LSN是一个一直递增的整型数字,表示事务写入到日志的字节总量.

  1. update操作后 ,LSN增长到110,几乎同时在缓存中更新数据页和redolog的LSN
  2. 4处到达检查点checkpoint,检查点会同时触发数据页和redolog刷盘,并且有机制保护数据页刷盘速度慢于redolog的刷盘速度。
  3. 等到数据页和日志页刷盘完毕,即到了位置⑤的时候,所有的LSN都等于300。
  4. 位置⑥触发了redolog刷盘的规则,但此时buffer中的日志LSN和磁盘中的日志LSN是一致的,所以不执行日志刷盘.刷盘规则如下
    1. 发出commit动作时。已经说明过,commit发出后是否刷日志由变量 innodb_flush_log_at_trx_commit 控制。
    2. 每秒刷一次。这个刷日志的频率由变量 innodb_flush_log_at_timeout 值决定,默认是1秒。要注意,这个刷日志频率和commit动作无关
  5. 随后执行了提交动作,即位置⑧。默认情况下,提交动作会触发日志刷盘,但不会触发数据刷盘

在启动innodb的时候,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。启动数据库时会检查磁盘中数据页的LSN,如果数据页的LSN小于日志中的LSN,则会从检查点开始根据 磁盘中的redolog恢复。

Redis

redis 数据存于内存中,因此读写速度快,用于缓存。还用于做分布式锁。

为什么用redis/缓存?

  1. 高性能 多次访问时,除了第一次从硬盘读取,之后都从内存读取,速度自然快很多。若数据库改变,同步改变缓存即可。
  2. 高并发 缓存能承受的请求数量远大于数据库

为什么要用 redis 而不用 map/guava 做缓存?

       redis,memcached是分布式缓存,在多实例情况下,各实例共享一份缓存,缺点是要保证高可用,架构较复杂。Java的map/guava是本地是缓存,生命周期同jvm,各实例保存一份缓存。

redis 和memcached 的区别

  •  四种常用IO模型

    • 同步/非同步 && 阻塞/非阻塞的概念理解:
      • 同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者。阻塞时进程不能做别的事,处理其他IO,非阻塞是进程可以做别的事。
    • 网络IO
      • I/O一般包括两个步骤:
      1. 数据从网络到达,并将其复制到内核缓冲区
      2. 数据从内核缓冲区复制到进程缓冲区
    • 同步阻塞模型:从应用程序执行系统调用recvfrom起,进程就开始阻塞,即使此使完整的udp数据报还没有到达内核

  • 同步非阻塞模型: “每隔一会儿瞄一眼进度条” 的轮询(polling)方式,数据没准备好时,执行系统调用内核返回一个错误,进程不会阻塞。进程仅在数据准备好之后第2步拷贝数据时阻塞。

 

  • 多路复用IO模型:与同步阻塞模型相比,select函数可以监听多个socket,只要有一个socket数据准备好了,select就会返回,应用进程就可以调用recvfrom处理数据。达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的

  • 异步非阻塞IO模型:用户进程发起aio_read操作之后,立刻就可以开始去做其它的事,然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal或执行一个基于线程的回调函数来完成这次 IO 处理过程,告诉它read操作完成了。

 

  • 区别一 网络模型:redis使用单线程阻塞IO多路复用模型,memchached是多线程非阻塞IO多路复用模型
  • 区别二  数据类型:redis支持String(key-value) HashMap ,set,list,zest(sorted-set)五种数据结构,memchached仅支持String一种数据类型。
  • 区别三 持久化:redis支持将内存中的数据持久化到硬盘中,memchached全部只在内存中
  • 区别四 集群模式:memcached没有原生的集群模式,只能通过一致性哈希算法(???)在客户端实现分布式存储。redis cluster在服务端实现了分布式存储。

如何用redis实现动态点赞

如何设计数据库

点赞、取消点赞是高频次的操作,若每次都读写数据库,大量的操作会影响数据库性能,所以需要做缓存

redis的hashmap所有数据都存在一个键里,通过这个键方便把所有点赞记录取出。hashmap中的每一项都是一个key-value  key为userId::postId(用::把点赞人和被点赞文章隔开,拆开就能得到userId和postId) value为点赞状态(1点赞,0取消点赞)

mysql中也建立点赞表用于持久化存储。被点赞用户id,点赞用户id,点赞状态。再加上主键id,创建时间,修改时间就行了。

开启定时任务(springboot  中用quartz)持久化到数据库

单个redis内存不足时,使用集群进行分片存储

分片就是把大的数据分成几个部分,分开存储。redis利用集群+槽位实现分片。一个redis集群包括16384个槽位(hash slot),数据库中的每个key都对应一个槽位,计算方法为CRC16(KEY)&16384,集群中的每个节点负责处理一部分槽位,如:

  • 节点 A 负责处理 0 号至 5500 号哈希槽。
  • 节点 B 负责处理 5501 号至 11000 号哈希槽。
  • 节点 C 负责处理 11001 号至 16384 号哈希槽。


集群模式下,解耦了key和节点的映射关系。redis节点接收任何与键有关的命令时要先计算键对应的槽,如果槽不在本节点,则通知客户端请求正确的节点,这个过程交moved重定向。多次重定向损耗性能,因此优秀的java客户端会在内部维护槽和节点之间的映射关系,有变化时再借助重定向更新映射关系。集群的伸缩(节点的增减)本质是槽在节点间的移动。比如增加一个节点D,则把节点A,B,C的部分槽移动到D上去。

集群模式下,同时进行大量点赞,如何避免数据不一致?使用分布式锁进行控制

  • 加锁在沙滩上踩一脚,留下自己的脚印,就对应了加锁操作。其他进程或者线程,看到沙滩上已经有脚印,证明锁已被别人持有,则等待。
  • 解锁把脚印从沙滩上抹去,就是解锁的过程。
  • 锁超时为了避免死锁,我们可以设置一阵风,在单位时间后刮起,将脚印自动抹去。

Redis实现锁的原理在于 SETNX命令。当 key不存在时将 key的值设为 value ,这个value要能标识加锁的线程,返回值为 1;若给定的 key 已经存在,则 SETNX不做任何动作,返回值为 0 

redis客户端redisson对分布式锁做了很好的封装

  RLock lock = redissonClient.getLock("stockLock");

 

 

 MongoDBEsmysql
数据存储形式

BSON文档(类似ES,JSON),相当于mysql中的一行

所有文档存储在集合中,集合类似mysql的表

index相当于库,type相当于表,document相当于行,Field相当于列。

mapping定义type下的字段规则,如字段类型,如何分词。

倒排索引:

分布式搜索引擎:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作;

Master-slave 架构,也实现了数据的分片和备份

查询方式MongoDB查询方式  
应用场景

模式灵活:数据表不确定,数据属性多样

高可用复制集

可扩展分片集群:集群水平扩展,可存海量数据

索引强大:检索快

PB级文本的检索和统计分析。

 

ELK用于故障日志,根据关键字利用倒排索引找到关键错误日志,可视化等

 

用两个条件来查询,比如 where A = a and B = b,如果我用A建立了索引,那么我再用B建立索引会不会提高查询速度?

不一定。当用多个单列索引时索引越多占内存空间越多。合并多个索引结果耗费性能(先用A索引找出符合A=a的结果,再用B索引找出符合B=b的结果,再把结果合并)

最好是对where条件里的列建立联合索引,如何选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列多列索引只能匹配最左前缀,也就是说:

select * from payment  where staff_id =  2205  AND customer_id =  93112 ;
select count(*)  from payment  where  customer_id =  93112 ;

可以利用索引,但是 不能利用索引。

select * from payment where staff_id = 2205 ;

数据库索引有哪几种类型

1.普通索引

2.唯一索引,要求索引列的值必须唯一,但允许有空值

3.主键索引,要求索引列是主键,这意味着索引列唯一且不为空

4.组合索引,在多个列上创建索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。

5.全文索引,类似搜索引擎,根据相关度匹配。

聚集索引和非聚集索引有什么区别

聚集索引的顺序和数据物理存储的顺序一样,类似于按拼音查字典,实际页码就是按照拼音顺序组织的。用B+树描述索引,聚集索引叶节点是数据。非聚集索引是按照数据的某些字段形成的目录,类似于按部首查字典,同一个部首的字在目录中是挨着的,但实际所在的页码并非如此。聚集索引叶节点还是索引,但是包含指向数据的指针,也包含数据的主键。

使用聚集索引查询速度更快,因为直接访问到数据,而且不用二次查询,二次查询指非聚集索引查到的叶节点只有主键和索引字段,如果要其他字段,则要再次去数据行中找。非聚集索引插入速度更快,因为其不必保证物理存储顺序。

聚集索引绝非主键索引,虽然聚集索引默认是主键字段,但给主键用聚集索引往往是一种资源浪费,因为id顺序并无意义,给日期这样的字段更有意义,因为文件经常按日期排序。聚集索引只允许在一个字段上使用,因为不同的两个字段逻辑顺序理论上不可能一致。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值