关于读写锁:https://blog.csdn.net/java_wxid/article/details/99165717
分布式事务(不同系统之间如何保证数据的一致性(A系统写入数据,B系统因为某些原因没有写入成功,造成数据不一致))关于分布式事物我看了有一篇博文感觉写的很好,这里我就引用他的地址:
https://www.cnblogs.com/soundcode/p/5590710.html
安全性问题(数据篡改(拿到别人的URL,篡改数据(金额)发送给系统))方法一:对插入的操作进行校验:一个请求的URL传入进来,根据参数找到对应的用户关联表,查询到用户的userid和用户登录后保存到redis中的userid进行对比。例如:传入参数为(订单id)和(优惠券id),拿(订单id)查询该订单的用户id,拿来和登录的用户id进行对比,判断是否为本人操作。拿(优惠券id)查询用户表是否领取了该优惠券,该优惠券是否可用。
方法二:前端传入一个加密的信息数据,后端给这个给这个数据解密,判断是否为同一用户。例如:将用户id+项目id+密钥生成一个token,传入后端解密,拿到用户id,项目id,密钥对比是否一致
方法三:权限框架:可以指定某些角色,用户的登录名称密码正确才可以访问,修改。例如:1.Spring Security 2.apache shiro
索引使用的限制条件,sql优化有哪些,数据同步问题(缓存和数据库),缓存优化索引使用的限制条件,sql优化有哪些
a,选取最适用的字段:在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。另外一 个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOTNULL, b,使用连接(JOIN)来代替子查询(Sub-Queries) c,使用联合(UNION)来代替手动创建的临时表 d,事物: a)要么语句块中每条语句都操作成功,要么都失败。换句话说,就是可以保持数据库中数据的一致性和完整 性。事物以BEGIN关键字开始,COMMIT关键字结束。在这之间的一条SQL操作失败,那么,ROLLBACK命令就可以 把数据库恢复到BEGIN开始之前的状态。 b) 是当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方 式,这样可以保证用户的操作不被其它的用户所干扰。 e,减少表关联,加入冗余字段 f,使用外键:锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。 g,使用索引 h,优化的查询语句 i,集群 j,读写分离 k,主从复制 l,分表 m,分库 o,适当的时候可以使用存储过程 限制:尽量用全职索引,最左前缀:查询从索引的最左前列开始并且不跳过索引中的列;索引列上不操作,范围之 后全失效; 不等空值还有OR,索引影响要注意;like以通配符%开头索引失效会变成全表扫描的操作,字符串不 加单引号索引失效数据同步问题(缓存和数据库),缓存优化
1.降低后端负载:对于高消耗的SQL:join结果集、分组统计结果;对这些结果进行缓存。 2.加速请求响应 3.大量写合并为批量写:如计数器先redis累加再批量写入DB 4.超时剔除:例如expire 5.主动更新:开发控制生命周期(最终一致性,时间间隔比较短) 6.缓存空对象 7.布隆过滤器拦截 8.命令本身的效率:例如sql优化,命令优化 9.网络次数:减少通信次数 10.降低接入成本:长连/连接池,NIO等。 11.IO访问合并 目的:要减少缓存重建次数、数据尽可能一致、减少潜在危险。 解决方案: 1.互斥锁setex,setnx: 如果 set(nx 和 ex) 结果为 true,说明此时没有其他线程重建缓存,那么当前线程执行缓存构建逻辑。 如果 setnx(nx 和 ex) 结果为 false,说明此时已经有其他线程正在执行构建缓存的工作,那么当前线程将休 息指定时间 ( 例如这里是 50 毫秒,取决于构建缓存的速度 ) 后,重新执行函数,直到获取到数据。 2永远不过期: 热点key,无非是并发特别大一级重建缓存时间比较长,如果直接设置过期时间,那么时间到的时候,巨大的访 问量会压迫到数据库上,所以要给热点key的val增加一个逻辑过期时间字段,并发访问的时候,判断这个逻辑 字段的时间值是否大于当前时间,大于了说明要对缓存进行更新了,那么这个时候,依然让所有线程访问老的 缓存,因为缓存并没有设置过期,但是另开一个线程对缓存进行重构。等重构成功,即执行了redis set操作 之后,所有的线程就可以访问到重构后的缓存中的新的内容了 从缓存层面来看,确实没有设置过期时间,所以不会出现热点 key 过期后产生的问题,也就是“物理”不过期。 从功能层面来看,为每个 value 设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。 一致性问题: 1.先删除缓存,然后在更新数据库,如果删除缓存失败,那就不要更新数据库,如果说删除缓存成功,而更新 数据库失败,那查询的时候只是从数据库里查了旧的数据而已,这样就能保持数据库与缓存的一致性。 2.先去缓存里看下有没有数据,如果没有,可以先去队列里看是否有相同数据在做更新,发现队列里有一个请 求了,那么就不要放新的操作进去了,用一个while(true)循环去查询缓存,循环个200MS左右再次发送到 队列里去,然后同步等待缓存更新完成。 初始化Bean对象有几个步骤,它的生命周期之前写过,这里就给一个地址:https://blog.csdn.net/java_wxid/article/details/84391519
。。。。。(待完善中)