自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Redis对秒杀场景的支持

第一阶段是秒杀活动前。这是因为,一旦请求查到有库存,就意味着发送该请求的用户获得了商品的购买资格,用户就会下单了。由于数据库的处理速度较慢,不能及时更新库存余量,这就会导致大量库存查验的请求读取到旧的库存值,并进行下单。Redis 中保存了库存量,而库存量的最新值又是数据库在维护,所以数据库更新后,还需要和 Redis 进行同步,这个过程增加了额外的操作逻辑,也带来了额外的开销。订单处理会涉及支付、商品出库、物流等多个关联操作,这些操作本身涉及数据库中的多张数据表,要保证处理的事务性,需要在数据库中完成。

2023-07-21 11:06:00 76 1

原创 redis的ACID

第一个是原子性:事务中的多个操作必须都完成,或者都不完成第二个是一致性:数据库中的数据在事务执行前后是一致的,例如转账业务中,无论事务是否成功,转账者和收款 人的总额应该是不变的;第三个是隔离性:数据库在执行一个事务的时候,其他操作无法存取正在执行事务访问的数据第四个是持久性:数据库执行事务后,数据的修改要被持久化保存下来。

2023-07-21 11:05:12 79 1

原创 Redis实现分布式锁

如果客户端 A 执行了 SETNX 命令加锁后,假设客户端 B 执行了 DEL 命令释放锁,此时,客户端 A 的锁就被误释放了。Redlock 算法的基本思路,是让客户端和多个独立的 Redis 实例依次请求加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁了,否则加锁失败。因为在加锁操作中,每个客户端都使用了一个唯一标识,所以在释放锁操作时,我们需要判断锁变量的值,是否等于执行释放锁操作的客户端的唯一标识。第一步是,客户端获取当前时间。

2023-07-21 11:04:41 71 1

原创 redis原子操作

Redis 会把整个 Lua 脚本作为一个整体执行,在执行的过程中不会被其他命令打断,从而保证了 Lua 脚本中操作的原子性。所以我们可以把读取,修改,写回,这三个步骤变成一个命令,单命令,再加上redis的互斥,就能保障并发控制了。为了实现并发访问的正确性,redis提供了两种方法,加锁和原子操作,但是由于加锁会降低redis的性能,所以推荐使用原子操作的方式。并发访问操作主要是对数据进行修改,分为读取,修改,写回这三步,如果不对其控制,会导致错误。比如INCR/DECR。

2023-07-21 11:04:09 168 1

原创 redis缓存污染

有些数据访问次数很少,被访问一次后很久都不会再被访问了,但是它们仍然占据了缓存空间,这就是缓存污染。

2023-07-21 11:03:17 29 1

原创 Redis缓存异常

其中先删除缓存值,再更新数据库的操作中,延迟双删是指执行删除的线程1在更新数据库后,sleep一段时间,让来读取这个数据的线程2读数据,发现缓存没有,然后从数据库中找到值更新过去,由于是并发执行的,这里线程2读到的可能是旧值,因此需要删除这个存到缓存的数据,然后sleep醒过来的线程1再进行删除线程2更新的缓存。缓存穿透是指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。第三种方案,在请求入口的前端进行请求检测。

2023-07-17 17:18:43 124 1

原创 redis缓存淘汰策略

当有新数据进入候选数据集后,如果候选数据集中的数据个数达到了 maxmemory-samples,Redis 就把候选数据集中 lru 字段值最小的数据淘汰出去。而且,当有数据被访问时,需要在链表上把该数据移动到 MRU 端,如果有大量数据被访问,就会带来很多链表移动操作,会很耗时,进而会降低 Redis 缓存性能。LRU 算法的全称是 Least Recently Used,从名字上就可以看出,这是按照最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来,而最近频繁使用的数据会留在缓存中。

2023-07-17 17:17:53 162 1

原创 旁路缓存,redis如何工作的

而写请求则全部交给数据库,在数据库中增删改,对于删除的数据来说,如果redis已经缓存了相应的数据,应用需要把这些缓存的数据删除,redis中就没有这些数据了。但是,和只读缓存不一样的是,在使用读写缓存时,最新的数据是在 Redis 中,而 Redis 是内存数据库,一旦出现掉电或宕机,内存中的数据就会丢失。对于读写缓存来说,除了读请求会发送到缓存进行处理(直接在缓存中查询数据是否存在),所有的写请求也会发送到缓存,在缓存中直接对数据进行增删改操作。首先,一个系统不同层的访问速度不一样,我们才需要缓存。

2023-07-17 17:17:02 60 1

原创 Redis变慢了

但是,AOF重写会进行大量的磁盘IO操作,同时,fsync又需要等到数据写到磁盘才能返回,当AOF重写压力大的时候,就会导致fsync阻塞,虽然它在子线程进行,但是主线程会监视子线程,如果子线程阻塞,主线程发现上一次给子线程的fsync没有执行完,那么它就会阻塞,性能变慢。除此之外,另外,在使用 AOF 日志时,为了避免日志文件不断增大,Redis 会执行 AOF 重写,生成体量缩小的新的 AOF 日志文件。如果超过25%的key过期了,则重复删除的操作,知道过期key的比率降到25%一下。

2023-07-17 17:16:27 103 1

原创 CPU架构对Redis性能的影响

但是在多CPU架构上,会出现一个问题,那就是如果应用程序在socket 1上面运行了一段时间,并且把数据存储到了内存中,然后它被调度到了socket 2上面运行,这个时候它想要访问当时存到socket 1下面内存的数据时候,这个操作会比直接访问和socket 直接相连的内存要慢。CPU多核,如果应用程序频繁的被不同核心所运行, 那么就会降低效率,因为这会导致频繁地上下文切换,因此,我们应该把一个redis实例和一个核心绑定,这样可以提升redis的性能,用taskset来绑定。

2023-07-17 17:15:49 62 1

原创 redis的异步机制

主线程通过一个链表形式的任务列表和子线程交互,当收到键值对删除和清空数据库的操作时,主线程会把这个操作封装成一个任务,放入到任务队列中,然后给客户端返回一个完成信息,表明删除已经完成。首先,什么是异步,所谓的异步线程机制,就是指,Redis 会启动一些子线程,然后把一些任务交给这些子线程,让它们在后台完成,而不再由主线程来执行这些任务。redis主线程启动后,会使用操作系统的函数创造三个子线程,分别由它们负责 AOF 日志写操作、键值对删除以及文件关闭的异步执行。集合全量查询和聚合操作。

2023-07-17 17:15:07 174 1

原创 Redis做消息队列

不过,在生产者在写入数据时,list不会主动通知消费者有新消息写入了,如果消费者要处理消息,只能一直不停调用RPOP命令,带来了性能损失,为了解决这个问题,redis提供了阻塞形式的BRPOP,客户端在没有读到队列数据时,自动阻塞,知道队列有新数据写入队列,再开始读取新数据。在使用消息队列时,消费者可以异步读取生产者消息,然后再进行处理。这样一来,即使生产者发送消息的速度远远超过了消费者处理消息的速度,生产者已经发送的消息也可以缓存在消息队列中,避免阻塞生产者,这是消息队列作为分布式组件通信的一大优势。

2023-07-14 17:45:40 154 1

原创 Redis的String类型

但采用集合类型时,一个 key 就对应一个集合的数据,能保存的数据多了很多,但也只用了一个 dictEntry,这样就节省了内存。redis会用一个全局哈希表来保存所有键值对,哈希表的每一项是一个dictEntry的结构体,用来指向一个键值对,其中用三个8字节的指针,分别指向key,value,next,共24字节。,但事情还没有完,Redis的内存分配库jemalloc,它并不是申请多大的空间就给多大的空间, 而是会比你申请的空间多分配到比这个数大的最近的2的次幂,这样可以减少频繁的分配空间。

2023-07-14 10:23:17 43 1

原创 redis哨兵机制

哨兵就是运行在redis上的一个进程,它有三个任务,监控,选主,通知。

2023-07-13 17:50:21 41 1

原创 redis主库和从库

首先,从库发送指令给主库,请求同步,主库接收到请求后,生成一个RDB文件,并且把所有数据都存进去,如何发给从库,从库接收到数据后,会把自己当下的数据清空,如何再装入主库来的数据。这个缓冲区是环形缓冲区,主库写入,从库读取,这样的操作流程,在发生网络断联的时候,主库继续在写入,则主库写入进度比从库读取进度要快,网络连接恢复的时候,从库发出请求,并且把自己读取到了哪里的位置发给主库,主库判断从库读取到的位置,然后和自己写入的位置进行比较,把这两者之间的数据发送给从库。读操作:主库和从库都可以进行读操作。

2023-07-13 17:48:34 89 1

原创 redis学习笔记(二)

内存中的数据某一刻的状态记录。对redis来说,就是把某一时刻的状态以文件的形式存入磁盘,RDB记录的是数据,不是AOF的命令,所以数据恢复起来很快。

2023-07-11 17:20:23 30 1

原创 Redis学习(一)

redis先执行命令,把数据写入内存,然后才记录日志。AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本形式保存的。

2023-07-10 20:15:34 51 1

原创 netty学习笔记(第二天)

池化最大的意义在于可以重用bytebuf,如果没有池化,每次都要创建新的bytebuf实例,这个操作对于直接内存代价昂贵,有了池化可以重用bytebuf池中的实例,并且采用内存分配算法提升分配效率,高并发时,池化也更节约内存,防止内存溢出。其中灰色为读指针已经读过的地方,为废弃的,绿色为写指针已经写了,读指针还没读的区域,为可读区域,蓝色部分为容量足够但写指针还没写的区域,为可写区域。池化,可以复用池中bytebuf实例,更节约内存,减少内存溢出的可能。所有的handle连成串,就是pipeline。

2023-07-07 20:05:47 35 1

原创 netty学习笔记(一)

ServerBootstrap() : 启动器,负责组装netty组件,启动服务器NioEventLoopGroup() : EventLoop是一个selector加上一个thread就是一个eventloop,即循环处理可读可写事件,既然是group就是组的意思,里面有BossEventLoop和WorkerEventLoop,分别处理accept和读写的事件NioServerSocketChannel() : 选择服务器ServerSocketChannel的实现,OIO,BIO。

2023-07-06 17:59:13 39 1

空空如也

空空如也

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

TA关注的人

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