为该网站做自适应,asp.net网站连接mysql,怎么自己在百度上做网站,网站制作方案包括哪些内容redisObject
redis任意数据的key和value都会被封装为一个RedisObject#xff0c;也叫redis对象#xff1a; 这就redis的头信息#xff0c;占有16个字节
redis中有两个热门数据结构
1.SkipList#xff0c;跳表#xff0c;首先是链表#xff0c;和普通链表有以下差异也叫redis对象 这就redis的头信息占有16个字节
redis中有两个热门数据结构
1.SkipList跳表首先是链表和普通链表有以下差异
元素按照升序排列存储节点可能包含多个指针指针跨度不同 那么跳表的特点有以下 跳跃表是一个有序的双向链表每个节点都可以包含多层指针层数是1到32之间的随机数不同层指针到下一个节点的跨度不同层级越高跨度越大增删改查效率与红黑树基本一致实现却更加简单。但空间复杂度更高 2.Sorted数据结构的特点
每组数据都包含score和memebermemeber唯一可根据score排序 所以SortedSet的底层数据结构是怎么样的 首先SortedSet需要能存储score和memeber值而且要快捷的根据member查询score因此底层有一个哈希表以member为键以score为value其次StoredSet还需要能根据score排序因此底层还维护了一个跳表当需要根据member查询score时就去哈希表中查询当需要根据score排序查询时则基于跳表查询 内存处理
1. 过期key处理
redis的本身是键值型数据库其所有数据都存在一个redisDB的结构体中其中包含两个哈希表
dict保存Redis中所有的键值对expires保存Redis中所有的设置了过期时间的KEY及其到期时间写入时间TTL Redis是何时删除过期KEY的呢 Redis并不会在KEY过期时立刻删除KEY因为要实现这样的效果就必须给每一个过期的KEY设置时钟并监控这些KEY的过期状态。无论对CPU还是内存都会带来极大的负担。 Redis的过期KEY删除策略有两种 惰性删除 周期删除 惰性删除顾明思议就是过期后不会立刻删除。那在什么时候删除呢 Redis会在每次访问KEY的时候判断当前KEY有没有设置过期时间如果有过期时间是否已经到期。 周期删除顾明思议是通过一个定时任务周期性的抽样部分过期的key然后执行删除。执行周期有两种 SLOW模式Redis会设置一个定时任务serverCron()按照server.hz的频率来执行过期key清理 FAST模式Redis的每个事件循环前执行过期key清理事件循环就是NIO事件处理的循环。 2. 内存淘汰策略
Redis支持8种不同的内存淘汰策略 noeviction 不淘汰任何key但是内存满时不允许写入新数据默认就是这种策略。 volatile-ttl 对设置了TTL的key比较key的剩余TTL值TTL越小越先被淘汰 allkeys-random对全体key 随机进行淘汰。也就是直接从db-dict中随机挑选 volatile-random对设置了TTL的key 随机进行淘汰。也就是从db-expires中随机挑选。 allkeys-lru 对全体key基于LRU算法进行淘汰 volatile-lru 对设置了TTL的key基于LRU算法进行淘汰 allkeys-lfu 对全体key基于LFU算法进行淘汰 volatile-lfu 对设置了TTL的key基于LFI算法进行淘汰
比较容易混淆的有两个算法 LRULeast Recently Used最近最久未使用。用当前时间减去最后一次访问时间这个值越大则淘汰优先级越高。 LFULeast Frequently Used最少频率使用。会统计每个key的访问频率值越小淘汰优先级越高。 缓存问题
1.缓存一致性
我们采用Cache aside方案这个方案就是由业务开发者在更新数据库的同时更新缓存。 如果是查询操作假如先查到redisredis中没有那就查数据库然后把这个数据缓存在redis并设置TTL。如果是增加数据那么之间不用管redis等下一次查到这个数据的时候再缓存在reids中如果是删除和修改那就直接把redis中的这个数据删除掉等下一次查询的时候再做缓存。但是这个是由线程安全问题的假如有一个线程在做修改操作那么它先会把redis中的数据删除然后这时有另一个线程执行查询操作查询操作看redis中没有这个数据就去把数据库的旧数据又缓存在redis中这时上一个线程又把数据库的数据修改了那么这时redis和数据库就出现了数据不一致问题。然后这个问题的出现是由于先删除redis再操作数据库。那么我们先操作数据库再操作redis就不会出现数据不一致了。 所以缓存一致性策略的最佳实践方案 1. 低一致性要求使用redis的key过期清理方案 2. 高一致性需求主动更新并以超时剔除作为兜底方案 读操作 缓存命中直接返回 缓存未命中则查询数据库并写入缓存设定超时时间 写操作 先写到数据库然后再删除缓存 要确保数据库与缓存操作的原子性同时成功或失败 2. 缓存穿透 由于数据库中不存在该数据那么缓存中肯定也不存在。因此不管请求该数据多少次缓存永远不可能建立请求永远会直达数据库。此为缓存穿透。 那么解决这个问题有两种方案缓存空值和布隆过滤器 缓存空值实现起来简单但是有额外的内存消耗
布隆过滤首先需要一个很长的bit数组默认数组中每一位都是0 然后还需要K个hash函数将元素基于这些hash函数做运算的结果映射到bit数组的不同位置并将这些位置置为1例如现在k3 hello经过运算得到3个角标1、5、12 world经过运算得到3个角标8、17、21 java经过运算得到3个角标17、25、28 此时我们要判断元素是否存在只需要再次基于K个hash函数做运算 得到K个角标判断每个角标的位置是不是1 只要全是1就证明元素存在 任意位置为0就证明元素一定不存在
假如某个元素本身并不存在也没添加到布隆过滤器过。但是由于存在hash碰撞的可能性这就会出现这个元素计算出的角标已经被其它元素置为1的情况。那么这个元素也会被误判为已经存在。
因此布隆过滤器的判断存在误差 当布隆过滤器认为元素不存在时它肯定不存在 当布隆过滤器认为元素存在时它可能存在也可能不存在
当bit数组越大、Hash函数K越复杂K越大时这个误判的概率也就越低。由于采用bit数组来标示数据即便4,294,967,296个bit位也只占512mb的空间
3. 缓存雪崩 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机导致大量请求到达数据库带来巨大压力。 常见的解决方案有 给不同的Key的TTL添加随机值这样KEY的过期时间不同不会大量KEY同时过期 利用Redis集群提高服务的可用性避免缓存服务宕机 给缓存业务添加降级限流策略降级就是直接拒绝一部分请求当然必要情况也可以熔断服务 给业务添加多级缓存比如先查询本地缓存本地缓存未命中再查询RedisRedis未命中再查询数据库。即便Redis宕机也还有本地缓存可以抗压力 4. 缓存击穿 缓存击穿问题也叫热点Key问题就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了无数的请求访问会在瞬间给数据库带来巨大的冲击。因为这个重建缓存的时间比较长这段时间内还有其他很多的线程来访问那么这些线程都是打到了数据库那一层面造成数据库压力猛然飙升 常见的解决方案有两种 互斥锁给重建缓存逻辑加锁避免多线程同时指向 逻辑过期热点key不要设置过期时间在活动结束后手动删除。