限流策略
...
幂等性
...
Redis切片集群哈希槽为什么是16384个
CRC16算法产生的hash值有16bit,该算法可以产生2^16-=65536个值。换句话说,值是分布在0~65535之间。那作者在做mod运算的时候,为什么不mod65536,而选择mod16384? 如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。在消息头中,最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是:65536÷8÷1024=8kb。因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽 redis的集群主节点数量基本不可能超过1000个。 集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。 那么,对于节点数在1000以内的redis...
HashMap的环形链表问题
在JDK1.7的时候,插入链表采用的是头插法,会先将一个需要迁移节点的next指向新位置,然后再将新位置设置成迁移节点。因此在多线程扩容的情况下,一个线程完成了两个节点的迁移,但是被调度到另一个还未完成的线程,就会出现循环链表的情况 在JDK1.8,采用了尾插法,只需要遍历一个个节点,挂在tail节点的后面即可,即使迁移过程有并发情况,指针也最多被复制两次
CopyOnWriteArrayList
CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也可以称这种容器为”写时复制器”,Java并发包中类似的容器还有CopyOnWriteSet 原理 初始化时候,CopyOnWriteArrayList内部维护了一个可变数组,用于存储元素 修改的时候,首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器 读操作直接在原数组上进行,因为读操作不会改变数据,所以读操作不会加锁 优点 我们可以对CopyOnWriteArrayList并发的读,而不需要加锁,采用了读写分离的思想,读和写不同的容器 缺点 内存占用问题:因为CopyOnWriteArrayList的写时复制机制,在写的时候,内存中会出现两个对象的内存,旧的对象和新写入的对象,可能会造成频繁的young gc和full...
堆的实现与堆排序
push:每次插入元素到堆的末尾。然后up调整该元素 pop:移除堆顶的元素,然后将堆尾的元素放到堆顶,down调整堆顶元素 down:自上而下调整,使得整个堆仍然是小根堆 up:自下而上调整,使得整个堆仍然是小根堆 注意,以上两个函数只能使得调整的那个元素到达正确位置,因此使用前要求其他元素作为根在正确位置 力扣23. 合并 K 个升序链表 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) :...
Redis集群
Redis集群架构有哪些 主从架构:选择一台作为主服务器,将数据同步多台到从服务器上,构建一主多从的的模式,主从之间读写分离。主服务器可读可写,发生写操作会同步给从服务器,而从服务器一般是只读,且主从之间同步是异步的,所以无法实现强一致性保证 哨兵集群:当Redis的主服务器出现故障的时候,需要手动进行恢复,为了解决这个问题,Redis增加了哨兵模式,哨兵监控主从服务器,如果主服务器宕机了,会选择一个从服务器作为主服务器,并通知给其他从服务器和客户端 切片集群:当数据量大到一定程序的时候,需要使用Redis切片集群方案,将数据分布在不同服务器上,以此来降低系统对单节点的依赖 切片集群过程: 根据键值对的key,按照CRC16算法计算出一个16bit 再用16bit值对16384取模得到一个模数,每个模数代表一个相应编号的哈希槽 哈希槽分配: 平均分配:使用cluster create命令创建Redis集群的时候,Redis会自动把所有哈希槽平均分布到集群节点上,比如有9个节点,就是16834/9 手动分配:使用cluster...
SQL语法
count主键和非主键的结果有什么不同?count() 是一个聚合函数,函数的参数不仅可以是字段名,也可以是其他任意表达式,该函数作用是统计符合查询条件的记录中,函数指定的参数不为 NULL 的记录有多少个 123select count(name) from t_order; 统计t_order表中,name不为null的字段有多少个 123select count(1) from t_order;统计t_order 表中,1 这个表达式不为 NULL 的记录有多少个t_order 表中,1 这个表达式不为 NULL 的记录 主键是不能存NULL值,因此会统计表中所有行数据的数量 非主键可以存NULL值,因此会统计表中这个列的非NULL值得数量 MySQL内连接,外连接有什么区别内连接(INNER JOIN)和外连接(LEFT JOIN和RIGHT...
MySQL高可用
MySQL主从复制的过程是怎么样的分为3个阶段: 写入binlog:主库修改数据后,会写入binlog日志,从库连接到主库后,主库会创建一个log dump线程,用于发送bin log的内容 同步binlog:从库会专门创建一个I/O线程来连接主库的log dump线程,来接受主库的binlog日志,再把binlog信息写入relay log的中继日志里,再返回给主库“复制成功”的响应 回放binlog:从库会专门创建一个用于回放binlog的SQL线程,去读relay...
Spring事务
Spring事务传播级别事务的传播机制定义了一个方法被另一个事务方法调用的时候,这个事务的方法行为该如何,定义了事务的边界和事务上下文在方法调用链中传播 Spring事务隔离级别ISOLATION_DEFAULT: 使用后端默认的事务隔离级别,MySQL是可重复读,Oracle是读已提交 ISOLATION_READ_UNCOMMIT: 读未提交 ISOLATION_READ_COMMIT: 读已提交 ISOLATION_REPEATABLE_READ: 可重复读 ISOLATION_SERIALIZABLE: 串行化 声明式事务失效的场景 MySQL存储引擎是MyISAM,不支持事务 Spring的声明式事务是基于代理模式的。由于java继承时, 不能重写 private , final , static 修饰的方法,所以private 方法, final 方法 和 static...