1, 锁
- 【什么是锁】锁是一种保护机制,在多线程的环境下,保证数据的正确性和一致性。
- 【锁有哪些】(悲观锁,乐观锁)(共享锁,排它锁锁)(公平锁,非公平锁)(分布式锁)(自旋锁)
- 【解释一下悲观锁和乐观锁】 悲观锁,总假设最坏情况,每次取数据时都认为别人会修改,所以在每次拿数据时都会上锁。共享资源每次只给一个线程使用,其他线程阻塞,等到用完才把资源转让给其他线程。
乐观锁,总假设最好的情况,每次取数据都会认为别人不会修改,所以不会上锁,如果要更新数据的时候会检查一下有没有其他线程在修改数据。乐观锁的两种实现:CAS(compare and swap),版本号。
CAS:
int compare_and_swap (int* reg, int oldval, intnewval)
{
int old_reg_val = *reg;
if(old_reg_val == oldval)
*reg = newval;
return old_reg_val;
}
类似于TS(Test and Set)这是一条原语,不可分割的函数执行过程。
boolean TS(boolean *lock){
boolean old = *lock;
*lock = true;
return old;
}
【解释共享锁和排它锁】共享锁又称为读锁,若事务给对象A上读锁,其他事务也可以上读锁,但是如果要修改数据,要等到所有事务释放锁之后才可以上写锁(排它锁)。
排它锁:又称为写锁,若一个事务上了写锁,那么它既可以读数据也可以写数据,其他事务要等他其他事务释放锁后才能上锁读写。保证数据只对上锁了的事务服务。【解释公平锁和非公平锁】
公平锁:线程按照他们请求的顺序获取锁
非公平锁:允许插队占用锁。【分布式锁】:
有redis分布式锁,用setnx指令,如果key不存在才创建,redis是单线程的,多个客户端请求只有一条可以设置key成功。不过是有缺陷的,得设置一个过期时间。【自旋锁】
两种锁的加锁原理
互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。
自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。
2,redis的持久化方式
有rdb(快照),aof(连续增量备份)
- 【RDB】也就是快照。快照是一种全量备份内存数据二进制序列话,存储上很紧凑。redis是单线程程序,要对外提供快速的服务,但是内存快照需要大量IO操作,会拖垮服务器性能。为了不阻塞线上业务,别持久化边响应客户端请求,使用系统多进程的COW(copy on write)机制。redis持久化时会fork产生一个子进程。刚创建时内存基本没什么变化,等到客户端进行修改值的时候,就会把修改数据的那一页调出来,redis持久化继续遍历原来的数据。
- 【AOF】日志存储的是Redis服务器的顺序指令,若恢复当前redis实例,就要aof重放,在redis里面跑一边日志,aof日志会越来越长 。aof重写会瘦身日志。