自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(47)
  • 收藏
  • 关注

转载 redis unlink

unlink是指redis用异步方式去del键值,但是异步删除键值有一个判断条件.会根据元素的个数来判断是否值得用异步线程去del,因为异步会有额外的消耗,如果元素较少(比如string,无论string多大都是在主线程里删除),直接在主线程里删除就行.List:直接返回element个数。Set:非hash table编码,即intset编码时返回1.当一个集合只包含整数值元素, 并且这个集合的元素数量不多时, Redis 就会使用intset作为集合键的底层实现。Hash:同上。当hash键值

2021-08-19 11:02:58 3248 1

原创 redis跳表的层数

redis跳表在插入一个元素时,先随机出一个该元素的所在的层数int random_level() { K = 1; while (random(0,1)) K++; return K; } 然后在将该元素加入第K层的链表中.

2021-08-16 15:22:13 862

原创 RocketMQ重试和死信队列

消息消费失败后,消息会进入到 RocketMQ 的重试队列中。比如说消费者所属的消息组名称为AAAConsumerGroup其重试队列名称就叫做%RETRY%AAAConsumerGroup重试队列中的消息过一段时间会再次发送给消费者,如果还是无法正常执行会再次进入重试队列默认重试16次,还是无法执行,消息就会从重试队列进入到死信队列重试队列中的消息重试16次任然无法执行,将会进入到死信队列死信队列的名字是 %DLQ%AAAConsumerGroup处理死信队列中的消息先要修改权限为可读写(默

2021-08-06 09:28:20 476

原创 mysql innodb

https://zhuanlan.zhihu.com/p/50560758磁盘和内存每页是4K,mysql的页是16K.B+数每个节点默认都是16K(可能不到16K),mysql一次读取一个节点.

2021-07-30 16:57:44 77

原创 cas锁的实现

CPU提供了在指令执行期间对总线加锁 的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK" ,经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。当然,并不是所有的指令前面都可以加lock前缀的,只有ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC,

2021-07-28 16:49:40 332

原创 缓存淘汰算法

LRU (Least Recently Used):这个名字有问题!!!它表达的含义应该是将最近未使用的淘汰掉,和’Least’(最少)没有任何关系。实现:用一个链表记录每个数据,使用到了哪个数据就将哪个数据放在链表的最前面,淘汰内存时将末尾的直接删除,和使用次数无关。LFU (Least frequently used) 最不经常使用,如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。这个实现需要将设置一个比例,关于时间和使用次数的比例需要经过不断的优化,可以参考Red

2021-07-27 15:15:02 42

原创 MMP FileChannel RandomAccessFile总结

RandomAccessFile用来随机读写一个文件,调用seek(long position)来标记从哪里开始读写,一般用来多线程的分块文件复制或者分块文件写入.它有一个方法去获取FileChannel.FileChannel用来访问文件,可以进行MMP、transferTo、transferFrom,但是不能随机读写。其中transferFrom将一个通道的数据写入当前通道,可以直接将接受到的数据流写入文件,不用经过用户态的处理数据流,但是一般都还是需要进行处理数据流的,因为数据都是由各种协议包装起来

2021-07-27 12:37:51 371

原创 spring-cloud-gateway 2.x跨域问题

先需要注入一个允许跨域的filter.@Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedMethod("*"); config.addAllowedOrigin("*"); conf

2021-07-22 09:39:14 271

原创 查看mysql binlog

mysqlbinlog --no-defaults [–database=t_user] --start-datetime=‘2021-07-06 00:00:00’ --stop-datetime=‘2021-07-06 11:00:00’ --base64-output=decode-rows -v binlog.000018 | moremysqlbinlog有一个参数–verbose(或-v),将自动生成带注释的SQL语句(在行事件中重构伪SQL语句),其实这个并非原始SQL语句,而是伪SQL

2021-07-06 10:53:00 72

原创 not exists和not in

select * from t1 where not exists (subQuery)判断subQuery是否结果为空,为空返回true.select * from t1 where id not in(subQuery)判断’‘subQuery=id’’,当subQuery的结果中含有null时,任何值和null比永远返回false.当subQuery含有null时,not in永远返回的是false,也就不会返回任何结果集....

2021-07-01 15:04:42 43

转载 arthas小问题

https://www.shangmayuan.com/a/90608722b13642628af2a371.html

2021-06-29 17:47:59 48

原创 redis分布式锁的思考

关于redis主节点宕机,导致分布式锁失效的思考:线程1先创建一个uuid,获取到key为A的锁,value为线程1创建的uuid,过期时间为3秒,再创建一个watchdog线程每隔一秒就去重置过期时间,在线程1执行完毕后去释放该锁。可能遇到的情况:当前jvm进行gc,stw导致所有的线程都无法进行正常工作,如果时间过长,导致锁过期了,那么就需要在释放锁的时候去判断当前锁是否存在,不存在的话就抛出异常,若存在且是别的线程拿到的锁,也要抛出异常。另一种极端的情况:若是redis主从集群,那么有可能在异步复

2021-06-29 15:16:25 138

原创 同步复制和异步刷盘

大多数中间件要保证数据不丢失的话可以采用同步复制和异步刷盘,因为刷盘的话消耗较大.

2021-06-28 16:39:09 128

原创 反向代理与重定向

1.nginx反向代理:客户端只请求了一次nginx,nginx去请求真正的服务端,服务端返回数据给nginx,nginx再返回数据给客户端,整个流程的流量都要经过nginx.2.重定向:客户端请求服务器,服务器告诉客户端:“我这里没这个资源,资源在我返回给你的url中.”,所以重定向时,返回给客户端的状态码是302而不是200,要不然就无法区分是不是需要重定向,客户端拿到302和url就会去请求这个url指定的资源....

2021-06-28 16:09:04 1015

原创 mybatis-plus-join

前言在有主键的前提下:1.含有其他索引字段: 用explain,会发现这三个执行流程一模一样,都用的是其他索引.2.不含其他索引字段: 用explain,会发现count(*)和count(1)用的是主键索引,count(col)是没用索引的.在没有主键的前提下:1.含有其他索引字段: 用explain,会发现这三个执行流程一模一样,都用的是其他索引.2.不含其他索引字段: 用explain,会发现count(*),count(1),count(col)这三个都是没用索引的.先说结

2021-06-17 18:32:57 2027

原创 es磁盘满了导致的异常

Caused by: org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=cluster_block_exception, reason=blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];]ES所在的系统出现磁盘满了的问题,占用95%的磁盘,删除后已用磁盘空间降至40%,但问题依然存在,需要重新修改一下属性值.解决方法:

2021-06-03 19:16:21 1503

原创 in 和 exists

A表数据数量为m,B表数据中和A有关的数据数量为n.select * from A where A.id in(select B.aid from B) 先执行子查询,将结果放到内存中,在执行主查询进行条件筛选.缓存n条数据,再用m条数据进行条件筛选,筛选m*n次.select * from A where exists( select 1 from B where B.aid = A.id)先执行主查询, 查出m条数据,再进行m次查询.in:for(int i = 0;i<m;i++){

2021-05-27 14:11:56 43

原创 go远程debug+热更新

用到两个开源工具:github.com/go-delve/delve和github.com/cosmtrek/airdelve用于远程debug,air用于热更新先配置export GOPATH=/root/gocode再配置export PATH=$GOPATH:bin,这样下载到/root/gocode/bin的可执行文件就能直接敲名字运行起来了.将自己工程demo的代码复制到GOPATH下进入/root/gocode/demo目录下载go get github.com/go-delve/de

2021-05-26 11:23:42 569

原创 mysql分组与case when

问题:一个学生成绩表,里面有语文,数学,英语等类型成绩,用type=(0,1,2)表示,求每一个学生分别参加过多少次语文,数学,英语,以及总共参加过多少次比赛,也就是要返回的列为:学生id语文次数数学次数英语次数总次数score表结构如下:student_idtypescore1010021100301001110020100321002310030100答案:select

2021-05-17 10:18:09 425 1

原创 mybatis-plus autoResultMap的小问题

PersonMapper.java: @Select("select * from person limit 1") Person get();Person.java:@TableName(value = "t_person", autoResultMap = true)@Datapublic class Person { @TableId private String id; private String name; @TableField(t

2021-05-11 12:11:12 3046

原创 虚拟机centos8网络

0桥接:对应vmware中VMnet0,会直接使用主机所在局域网的ip,如果被占满了,就使用不了了.1nat:,对应vmware中VMnet8,相当于用vmware生成了一个局域网.如果进去没有网络:输入nmcli n,返回disable,就输入nmcli n on打开网络输入nmcli device connect ens33...

2021-04-30 14:29:00 51

原创 bitmap以及布隆过滤器

bitmap直接使用会占用固定大小内存,建议使用org.roaringbitmap.RoaringBitmap这个实现类.布隆过滤器就是对同一个对象使用多个不同的hash函数,产生多个hash值,将这些hash值所在位置置为1,也就是bitmap[hash] = 1.将10亿个黑名单ip进行hash放入bitmap,hash值肯定会重复.这时有一个正常ip,经过这些hash函数产生了不同的hash值,如果这些值所在的位置都是1,那么就会误判成为在黑名单中;只要有一个bitmap[hash]=0,那么就

2021-04-29 18:07:03 266

原创 redis防止击穿

如果是分布式项目就用redis创建一个分布式锁(不是分布式就用jdk自带的锁):pubic Object query(QueryParam params){ Object result = null; String lockKey = "lock:" + JSON.toJSONString(params); result = redis.get(JSON.toJSONString(params)); if(result == null){ redis.lock(lockKey) try{

2021-04-29 17:52:29 80

原创 如何选用redis中key类型

在实际开发中,我之前很纠结用什么类型,尤其是hash和string的区别.整个redis比喻成一个Map<String,Object>,string相当于Object=String,hash相当于Object=Map<String,Object>.两者的优缺点:将多个键放在hash里面会省内存,但是无法给每个单独的键设置过期时间;将多个键放在string里面消耗内存,但是可以给每个单独的键设置过期时间;同理:list,set,zset也无法给各自里面的元素设置过期时间.

2021-04-28 15:08:44 108

原创 docker指定ip

Docker 默认网络Docker安装后,默认会创建下面三种网络类型:启动 Docker的时候,用 --network参数,可以指定网络类型,如:docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest/bin/bashbridge:桥接网络默认情况下启动的Docker容器,都是使用 bridge,Docker安装时创建的桥接网络,每次Docker容器重启时,会按照顺序获取对应的IP地址,

2021-04-22 11:56:33 305

原创 token刷新

private static final Logger logger = LoggerFactory.getLogger(LoginTools.class); /** * 用户token,eg. token:1245637858 */ private final static String TOKEN_KEY = "token:%s"; /** * 在多长时间内用户不用再次登录,比如3月1日登录了,expires为7天,那么用户 * 在3月8日

2021-04-15 20:51:01 144

原创 https通讯协议

http://www.360doc.com/content/13/0809/14/1073512_305848184.shtml

2021-04-08 20:39:49 40

原创 mysql8主从复制

mysql5.7时允许多线程复制,原理是同时处于prepared的事务都是可以并行执行的,因为能进入prepared阶段的说明已经拿到了锁,既然不同的事务同时拿到了锁,那么就不可能冲突,所以可以同时执行的.AtomicInteger globalTransactionId;thread1:{ beginTransaction(); excute("update user set age = 10"); commit();}thread2:{ beginTransaction(); exc

2021-04-08 12:43:58 60

原创 mysql8主从

grant replication slave on . to ‘test’@’%’ identified by ‘123456’;上面语句在mysql8中无法执行,修改为两步:create user ‘test’@’%’ identified by ‘123456’;grant replication slave on . to ‘test’@’%’;注意:master和slave的server_id不能一样,通过命令来修改:set global server_id=2修改后查看:show

2021-04-07 18:17:49 88

原创 java泛型

比如有一个类Base和泛型Textendsextends的前面可以是 ?,Textends的后面可以是T,Base? extends T? extends BaseT extends KT extends Base??只能在super和extends的最前面? extends T? extends Base? super T? super Basesupersuper的前面只能是?super的后面可以是T,Base? super T? super Base&这

2021-04-02 18:12:23 38

原创 秒杀系统的个人理解

1.所有的静态页面不要和秒杀服务器放在一起,最好是放在cdn服务器上,减少流量的压力.2.将要被秒杀的商品相关信息放入redis缓存中,比如数量等.3.用户抢购时,直接使用decrease减少数量,减少到0就不再减少,减少请求成功的用户就相当于抢购成功,减少请求失败的用户就直接返回.一般情况下,商品抢购的数量不会很多,差不多也就几百几千几万,如果就是几百或者几千,可以直接让抢购成功的用户下单入库,不用经过消息队列消除峰值,几百几千的tps数据库还是能顶住的.4.如果是几千上万的并发量,那么mysql就

2021-03-30 14:01:40 48

原创 synchronized和ReentrantLock

这两者的性能是差不多的,当只有一个线程访问时,也就是没有竞争时,相当于没有锁.当有多个线程竞争时,synchronized引入轻量级锁,使用自适应自旋,即根据以往的自旋等待时能否获取到锁,来动态调整自旋的时间,在这个时间段没获取到锁就要变为重量级锁,重量级锁就是没获取到锁时就会由系统内核挂起,获取到锁又系统内核唤醒,比较耗费资源.而ReentrantLock在阻塞前会调用2~3次cas操作尝试获取锁,获取失败就会由LockSupport.park()挂起,也是系统内核挂起,比较耗费资源.个人认为syn

2021-03-29 18:06:26 48

原创 ReentrantLock公平与非公平

公平锁final void lock() { acquire(1);}非公平锁final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1);}公平锁与非公平锁的公平体现在加锁的时候.比如,有10个线程在等待,一个线程在工作,等到这个线程完成后,10个等待线程中的第一个会被唤醒,唤醒后该线程去获取锁,这个时候如果

2021-03-29 17:08:00 76

原创 2021-03-26

一个数a%32 = 1,那么a%64=1+32 或者 a%64=1,只有这两种情况.因为 a = 32*b+1,如果b为奇数,那么a%64=1+32,如果b为偶数,那么a%64=1.在红黑树中,红黑树是个二叉搜索树,一个节点左边的都比这个节点小,右边的都比这个节点大,...

2021-03-26 19:22:09 38

原创 2021-03-25

1.REDIS集群普通hash算法:假设有3台master主机,所有键值对的hash值取值范围为30000(具体是多少不清楚),那么用第k台机器的所有键值就是10000*(k-1) ~ 10000*k。一旦有一个机器挂掉,那么去获取hash值为200时,就会去第(200%(3-1))=0个机器上去,显然是去不到的,因为它本来是存在第(200%3)=2个机器上。一致性hash算法:假设有3台master主机,所有键值对的hash值取值范围为30000(具体是多少不清楚)。分布如下图。A节点的hash值为

2021-03-25 19:05:28 46

原创 rocketmq事务

Rocketmq分布式事务,分为两个阶段:prepare: 1生产者产生一个’’预生产’’消息,一般会建一个transaction表记录所有的事务消息,该消息会有一个唯一的transaction_id:失败:事务回滚.2 将’’预生产’’消息发送至mq:失败:事务回滚.3 mq收到’’预生产’’消息,发送确认信息给生产者:失败:’’预生产消息’’并不会被消费者看见,也就无法消费,过段时间就被删除掉了,生产者也无法进行下一步,生产者事务回滚.4 生产者收到了确认消息,进行生产事务,生产出一个产品:失败

2021-03-25 19:02:51 66

原创 建造者模式-变种

该变种建造者可以强制用户按照某个顺序建造,并且防止了缺少字段缺点:在必需的字段必须建造一个类public static void main(String[] args) { User user = User.builder() .age(10) .name("zhaojin"); System.out.println(user); } @Data public static clas

2021-03-25 18:30:08 77

原创 EnumSet

EnumSet是一个抽象类.它的实现类有两个RegularEnumSet,JumboEnumSet.当创建EnumSet时,会根据传入值的枚举类型获取该枚举类型的所有值并缓存下来,并根据该枚举类型的所有数量判断该创建RegularEnumSet还是JumboEnumSet,数量<=64创建RegularEnumSet,>64就创建JumboEnumSet.RegularEnumSet该类用一个long值保存了所有的枚举类型,因为long是64位,也就是可以放64个0或者1,0表示不存

2021-03-25 17:14:35 32

原创 spring bean的初始化

new Bean();调用@autowired的setter方法执行@PostConstruct注解的方法执行InitializingBean的实现方法执行bean指定的initMethod方法

2021-03-25 15:02:23 25

原创 rocketmq发送消息,保存消息,获取消息

上图是大概的流程.发送消息producer发送消息时从namesever获取该消息topic的所有messageQueue,从这些messageQueue中随机抽取一个发送,当然也可以指定一个发送,broker给一个响应这样可以保证消息的有序性,因为只有一个messageQueue保存了该topic下的所有消息,而且消费者消费的队列是固定的.就算这个消费者宕机了,来接手这个messageQueue的新消费者也是从这个messageQueue一个一个取出来的,不用担心顺序会乱.如果broke.

2021-03-24 16:58:34 232

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除