【Redis从入门到放弃系列 十二】Redis的删除策略

其实同ElasticSearch的延迟删除【在段合并的时候才真正删除数据】【ElasticSearch从入门到放弃系列 九】Elasticsearch原理机制探索一样,Redis也不是马上删除数据,而是先进行标记,让其在内存中再多呆一会儿,等到满足一定条件的时候再进行统一删除。
在这里插入图片描述

什么是过期数据

当我们执行del删除redis数据以及expire过期的 ,过期数据:Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态:

127.0.0.1:6379> clear
127.0.0.1:6379> set name tml
OK
127.0.0.1:6379> set age 23 ex 30
OK
127.0.0.1:6379> set color red
OK
127.0.0.1:6379> del color
(integer) 1
127.0.0.1:6379> ttl name             -1:永久有效的数据 
(integer) -1
127.0.0.1:6379> ttl age              XX:具有时效性的数据,返回剩余时间
(integer) 5
127.0.0.1:6379> ttl color            -2:已经过期的数据、被删除的数据、未定义的数据
(integer) -2
127.0.0.1:6379> 
127.0.0.1:6379> ttl age
(integer) -2
127.0.0.1:6379> set second
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> ttl second
(integer) -2
127.0.0.1:6379> 

在这里插入图片描述
所以过期数据就是ttl返回为-2的三种状态的数据,要删除的数据。为了防止CPU压力过大,采取不同的删除策略。

过期数据的删除策略

和ElasticSearch的定期段合并策略相同,Redis处理过期数据也有一套。时效性数据的内存结构如下,有个espires的hash结构来存储数据的内存地址和时间,到时删除
在这里插入图片描述
删除策略的目标是在内存占用和CPU性能之间寻找一种平衡,既不能让过期数据过多,又不能让CPU太忙。目前有三种处理策略:

定时删除

创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作。
在这里插入图片描述

  • 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
  • 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量

总而言之一句话:牺牲时间换取空间

惰性删除

定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。过期key,依然停留在内存里,除非访问一下过期key,才会被redis给删除掉。这就是所谓的惰性删除。expireIfNeeded(),检查数据是否过期,执行get的时候调用
在这里插入图片描述

  • 优点:节约CPU性能,发现必须删除的时候才删除
  • 缺点:内存压力很大,出现长期占用内存的数据

总而言之一句话:牺牲空间换时间

定期删除

当然同AOF的几种策略相比,删除策略也不会走极端,于是就有了定期删除的策略:
在这里插入图片描述
这几个参数在配置中可以指定:

hz 10

周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度.

  • 优点: CPU性能占用设置有峰值,检测频度可自定义设置,内存压力不是很大,长期占用内存的冷数据会被持续清理

总而言之一句话:空间和时间具有平衡性

删除策略对比

三种删除策略及对比如下:

删除策略特点执行特点总结
定时删除节约内存,消耗CPU不分时段执行,内存占用低,CPU损耗高牺牲时间换空间
定惰性删除内存占用验证,CPU消耗低延迟执行,内存占用高,CPU损耗低牺牲空间换时间
定期删除内存定期随机清理每秒花费固定CPU资源维护内存,处理时间久的冷数据定时抽查,重点抽查

一般会组合惰性删除定期删除进行使用。

Redis的逐出算法

当新数据进入redis时,如果内存不足怎么办?Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法

逐出算法

首先需要注意几个参数,这几个参数决定了逐出算法的后续逻辑。

  • 最大可使用内存maxmemory:占用物理内存的比例,默认值为0,表示不限制。通常设置在50%以上
  • 每次选取待删除数据的个数maxmemory-samples: 选取数据时并不会全库扫描,导致严重的性能损耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据
  • 删除策略maxmemory-policy :达到最大内存后,对被选出来的数据进行删除的策略

逐出算法有三大类:

检测易失性数据(可能会过期的数据集server.db[i].expires)

检测易失数据有四种算法:

  • volatile-lru --> 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
  • volatile-lfu–>从已设置过期时间的数据集中挑选最不经常使用的数据淘汰
  • volatile-ttl–>从已设置过期时间的数据集中挑选将要过期的数据淘汰
  • volatile-random -->从已设置过期时间的数据集中任意选择数据淘汰

在这里插入图片描述

检测全库数据(所有数据集server.db[i].dict)

检测易失数据有三种算法:

  • allkeys-lru --> 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(最常用)
  • allkeys-random–>从数据集中任意选择数据淘汰
  • allkeys-lfu–>当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key

因为不需要关心数据是否过期,所以没有volatile-ttl

放弃数据驱逐

no-eviction–>禁止驱逐数据(redis4.0默认策略),也就是说当内存不足以容纳新写入数据时,新写入操作或报错,回引发OOM(Out of memory)

综合以上,我们推荐使用的策略是:maxmemory-policy volatile-lru

无法逐出的情况

逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求【均无过期数据,且占用内存已满】,将出现错误信息。

(err)OOM command not allowed when used memory > 'maxmemory'

以上所有的信息均可以通过info来进行查看:

127.0.0.1:6379> info
# Server
redis_version:6.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:4c35dfe260ddf15c
redis_mode:standalone
os:Linux 3.10.0-1127.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:9.3.1
process_id:44507
run_id:14ab8c5119da4c338a94724975bb50054d3e9ce0
tcp_port:6379
uptime_in_seconds:70012
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:9778284
executable:/root/redis-6.0.8/redis-server
config_file:/root/redis-6.0.8/config/redis-6379.conf
io_threads_active:0

# Clients
connected_clients:2
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
clients_in_timeout_table:0

# Memory
used_memory:946288
used_memory_human:924.11K
used_memory_rss:2076672
used_memory_rss_human:1.98M
used_memory_peak:946288
used_memory_peak_human:924.11K
used_memory_peak_perc:100.14%
used_memory_overhead:910474
used_memory_startup:876184
used_memory_dataset:35814
used_memory_dataset_perc:51.09%
allocator_allocated:912048
allocator_active:2038784
allocator_resident:2038784
total_system_memory:1019609088
total_system_memory_human:972.38M
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:2.24
allocator_frag_bytes:1126736
allocator_rss_ratio:1.00
allocator_rss_bytes:0
rss_overhead_ratio:1.02
rss_overhead_bytes:37888
mem_fragmentation_ratio:2.28
mem_fragmentation_bytes:1164624
mem_not_counted_for_evict:174
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:33972
mem_aof_buffer:174
mem_allocator:libc
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1603597171
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:98304
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:139264
module_fork_in_progress:0
module_fork_last_cow_size:0
aof_current_size:1339
aof_base_size:105
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

# Stats
total_connections_received:7
total_commands_processed:97
instantaneous_ops_per_sec:0
total_net_input_bytes:2632
total_net_output_bytes:131444
instantaneous_input_kbps:0.01
instantaneous_output_kbps:11.36
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:2
expired_stale_perc:0.00
expired_time_cap_reached_count:0
expire_cycle_cpu_milliseconds:334
evicted_keys:0
keyspace_hits:12
keyspace_misses:6
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:165
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
tracking_total_keys:0
tracking_total_items:0
tracking_total_prefixes:0
unexpected_error_replies:0
total_reads_processed:117
total_writes_processed:111
io_threaded_reads_processed:0
io_threaded_writes_processed:0

# Replication
role:master
connected_slaves:0
master_replid:d71bf05a8550a15cb81e049e7baef5451dc8fd3f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:17.306819
used_cpu_user:10.844898
used_cpu_sys_children:0.014531
used_cpu_user_children:0.014085

# Modules

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=2,expires=0,avg_ttl=0
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值