目录
分布式id的生成方案有哪些
雪花算法生成的ID由哪些部分组成
分布式锁在项目中有哪些应用场景?
分布式锁有哪些解决方案
Redis做分布式锁用什么命令
Redis做分布式锁,死锁有哪些情况?如何解决
Redis如何做分布式锁
MySQL如何做分布式锁
什么是分布式系统中的幂等
幂等有哪些技术解决方案
分布式微服务项目你是如何设计的编辑
分布式架构下,Session共享有什么方案?
分布式id的生成方案有哪些
UUID,数据库主健自增,Redis自增ID,雪花算法。
描述 | 优点 | 缺点 | |
UUID | UUID是通用唯—标识码的缩写,其目的是让分布式爆统中的所有元素都有唯一的辨识信息,而不需要通过中央控制器来指定唯—标识。 | 1.降低全局节点的压力,使得主键生成速度更快; 3.跨服务器合并数据方便。 | 1.UUID占用16个字符,空间占用较多; 2.不是递增有序的数字,数据写入IO随机性很大,且索引效率下降 |
数据库主键自增 | MySQL数据库设置主键且主键自动增长 | 1.INT和BIGINT类型占用空间较小; 2.主键自动增长,IO写入连续性好; 3.数字类型查询速度优于字符串 | 1.并发性能不高,受限于数据库性能; 3.自增:数据和数据量泄露 |
Redis自增 | Redis计数器,原子性自增 | 使用内存,并发性能好 | 1.数据丢失; 2.自增:数据量泄露 |
雪花算法 (snowflake) | 大名鼎鼎的雪花算法,分布式ID的经典解决方案 | 1.不依赖外部组件; 2.性能教好 | 时钟回拨 |
雪花算法生成的ID由哪些部分组成
1.符号位,占用1位。
2.时间戳,占用41位,可以支持69年的时间跨度。
3.机器ID,占用10位。
4.序列号,占用12位。一毫秒可以生成4095个ID。
分布式锁在项目中有哪些应用场景?
使用分布式锁的场景一般需要满足以下场景:
1.系统是一个分布式系统,集群集群,java的锁已经锁不住了。
⒉操作共享资源,比如库里唯一的用户数据。
3.同步访问,即多个进程同时操作共享资源。
分布式锁有哪些解决方案
1.Reids的分布式锁,很多大公司会基于Reidis做扩展开发。setnx key value ex 10s,Redisson.watch dog.
2.基于Zookeeper。临时节点,顺序节点。
3.基于数据库,比如Mysql。主键或唯—索引的唯—性。
Redis做分布式锁用什么命令
SETNX
格式: setnx key value将key的值设为value,当且仅当key不存在。若给定的 key 已经存在,则SETNX不做任何动作,操作失败。
SETNX是『SET if Not eXists』(如果不存在,则SET)的简写。
加锁: set key value nx ex 10s
释放锁:delete key
Redis做分布式锁,死锁有哪些情况?如何解决
情况1∶加锁,没有释放锁。需要加释放锁的操作。比如delete key。
情况2:加锁后,程序还没有执行释放锁,程序挂了。需要用的key的过期机制。
Redis如何做分布式锁
假设有两个服务A、B都希望获得锁,执行过程大致如下:
Step1:服务A为了获得锁,向Redis发起如下命令:SET productld:lock Oxx9p03001NXEX 30000其中,"productld"由自己定义,可以是与本次业务有关的id,"Oxx9p03001"是一串随机值,必须保证全局唯
一,“NX"指的是当且仅当key(也就是案例中的"productld:lock")在Redis中不存在时,返回执行成功,否则执行失败。"EX 30000"指的是在30秒后,key将被自动删除。执行命令后返回成功,表明服务成功的获得了锁。
Step2:服务B为了获得锁,向Redis发起同样的命令:SET productld:lock 0000111 NX EX 30000
由于Redis内已经存在同名key,且并未过期,因此命令执行失败,服务B未能获得锁。服务B进入循环请求状态,比如每隔1秒钟(自行设置)向Redis发送请求,直到执行成功并获得锁。
Step3:服务A的业务代码执行时长超过了30秒,导致key超时,因此Redis自动删除了key。此时服务B再次发送命令执行成功,假设本次请求中设置的value值为0000222。此时需要在服务A中对key进行续期。
Step4:服务A执行完毕,为了释放锁,服务A会主动向Redis发起删除key的请求。注意:在删除key之前,一定要判断服务A持有的value与Redis内存储的value是否一致。比如当前场景下,Redis中的锁早就不是服务A持有的那一把了,而是由服务2创建,如果贸然使用服务A持有的key来删除锁,则会误将服务2的锁释放掉。此外,由于删除锁时涉及到一系列判断逻辑,因此一般使用lua脚本。
MySQL如何做分布式锁
在Mysql中创建一张表,设置一个主键或者UNIQUE KEY这个KEY就是要锁的KEY,所以同一个KEY在mysq|表里只能插入一次了,这样对锁的竞争就交给了数据库,处理同一个KEY数据库保证了只有一个节点能插入成功,其他节点都会插入失败。
DB分布式锁的实现:通过主键id 或者唯一索性的唯一性进行加锁,说白了就是加锁的形式是向一张表中插入一条数据,该条数据的id就是一把分布式锁,例如当一次请求插入了一条id为1的数据,其他想要进行插入数据的并发请求必须等第一次请求执行完成后删除这条id为1的数据才能继续插入,实现了分布式锁的功能。
什么是分布式系统中的幂等
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。
例如,“getUsername()和setTrue()"函数就是一个幂等函数.更复杂的操作幂等保证是利用唯一交易号(流水号)实现.我的理解:幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。
幂等有哪些技术解决方案
1.查询操作
查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作;
2删除操作
删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个。
3.唯一索引
防止新增脏数据。比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建多个资金账户,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录。要点:唯一索引或唯一组合索引来防止新增数据存在脏数据(当表存在唯一索引,并发时新增报错时,再查询一次就可以了,数据应该已经存在了,返回结果即可。
4.token机制
防止页面重复提交。
业务要求:页面的数据只能被点击提交一次;
发生原因:由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交;
解决办法:集群环境采用token加 redis(redis单线程的,处理需要排队);单JVM环境:采用token 加redis或token 加jvm锁。
处理流程:
1.数据提交前要向服务的申请token,token 放到redis或 jvm内存,token有效时间;
2.提交后后台校验token,同时删除 token,生成新的token返回。
token特点:要申请,一次有效性,可以限流。
注意: redis 要用删除操作来判断token,删除成功代表token校验通过。
5.traceld
操作时唯一的。
分布式微服务项目你是如何设计的
分布式架构下,Session共享有什么方案?
1.不要有session:但是确实在某些场景下,是可以没有session的,其实在很多接口类系统当中
都提倡【API
无状态服务】;也就是每一次的接口访问,都不依赖于session、不依赖于前一次的接口访问,用jwt的token;
2.存入cookie中:将session存储到cookie中,但是缺点也很明显,例如每次请求都得带着session,数据存储在客户端本地,是有风险的;
3.session同步:对个服务器之间同步session,这样可以保证每个服务器上都有全部的session信息,不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败;
4.我们现在的系统会把session放到Redis中存储,虽然架构上变得复杂,并且需要多访问一次Redis,但是这种方案带来的好处也是很大的:实现session共享,可以水平扩展(增加Redis服务器),服务器重启session不丢失(不过也要注意session在Redis中的刷新/失效机制),不仅可以跨服务器session共享,甚至可以跨平台(例如网页端和APP端)进行共享。
5.使用Nginx(或其他复杂均衡软硬件)中的ip绑定策略,同一个ip只能在指定的同一个机器访问
但是这样做风险也比较大,而且也是去了负载均衡的意义;