Yundong Zhang Software Engineer

Hi 👋 I’m Yundong, a software engineer, bug maker, professional daydreamer, and minimalist based in Hangzhou, China.

I develop things as a Fullstack Software Engineer at Starblink. Previously, I worked as a Senior Backend Software Engineer at Xingyue Group, a Senior Backend Software Engineer at Bestdealer, and a Recommendation System Engineer at Klarna.

Writing

  • Year
  • Title
  • Index
  • 2024
  • Markdown Test
  • 1
  • 2023
  • Redis 碎片化问题
  • 2
  • 2015
  • Emoji Test
  • 3
Writing
Markdown Test
July 20, 2024 2,999 views
Markdown Test

h1

h2

h3

h4

h5

IMAGE

screenshot-1721458572035.png

CODE

public static void main(String[] strs){
    System.out.print("hello, world!");
}
Redis 碎片化问题
March 10, 2023 2,999 views
Redis 碎片化问题

1. 什么是 Redis 碎片化?

操作系统为你分配了 32 字节的连续内存空间,而你存储数据实际只需要使用 24 字节内存空间,那这多余出来的 8 字节内存空间如果后续没办法再被分配存储其他数据的话,就可以被称为内存碎片。

Redis 内存碎片虽然不会影响 Redis 性能,但是会增加内存消耗。

Redis 内存碎片产生比较常见的 2 个原因:

主要是两类原因 [存储], [回收]

  1. [存储] Redis 存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间

    image-20240417145028510

    例如:当程序申请的内存最接近某个固定值时,jemalloc 会给它分配相应大小的空间,就比如说程序需要申请 17 字节的内存,jemalloc 会直接给它分配 32 字节的内存,这样会导致有 15 字节内存的浪费。不过,jemalloc 专门针对内存碎片问题做了优化,一般不会存在过度碎片化的问题。

    Redis 一共有三种内容分配器 libc、jemalloc(默认)、tcmalloc. 无论哪种都会导致碎片化问题

    1. libc malloc:这是 C 语言标准库中提供的默认内存分配器。它是在大多数系统上都可用的通用内存分配器。但在高并发和大规模应用中,性能可能不如其他专门设计的分配器。
    2. jemalloc:jemalloc 是由 FreeBSD 社区开发的一种高性能内存分配器。它在多核系统上表现出色,并且专为多线程应用程序设计。jemalloc 提供了更好的内存分配和释放性能,以及更低的碎片化。它在很多大规模应用和高性能系统中被广泛使用,比如 Facebook 和 Netflix。
    3. tcmalloc:tcmalloc 是由 Google 开发的内存分配器,旨在提高大规模分布式系统的性能。它专为多线程环境和大型内存分配而设计,并提供了更好的内存利用率和更低的锁竞争。tcmalloc 通常在 Google 的各种服务中使用,例如 Gmail 和 Google Chrome。

    非必要无需修改,鱼和熊掌不可兼得

  2. [回收] 频繁修改 Redis 中的数据也会产生内存碎片。

​ 当 Redis 中的某个数据删除时,Redis 通常不会轻易释放内存给操作系统。

​ 例如,你想移除一个 20 字节大小的内存放入,13字节的数据。 Redis 就会产生 7 字节的内存碎片

2. 如何查看 Redis 内存碎片的信息?

使用 info memory 命令即可查看 Redis 内存相关的信息。下图中每个参数具体的含义,Redis 官方文档有详细的介绍:https://redis.io/commands/INFO 。

image-20240417150557759

mem_fragmentation_ratio = used_memory_rss / used_memory

内存碎片率 = 操作系统实际分配给 Redis 的物理内存空间大小 / Redis 内存分配器为了存储数据实际申请使用的内存空间大小

通常情况下,我们认为 mem_fragmentation_ratio > 1.5 的话才需要清理内存碎片。mem_fragmentation_ratio > 1.5 意味着你使用 Redis 存储实际大小 2G 的数据需要使用大于 3G 的内存。

⚠️ mem_fragmentation_ratio > 1.5 只是以为着可能有碎片, 如果你 1G 内存的 Redis 只放了 1M 的内容那么 mem_fragmentation_ratio 一定大于 1.5

3. 如何清理 Redis 内存碎片?

Redis4.0-RC3 版本以后自带了内存整理,可以避免内存碎片率过大的问题。

直接通过 config set 命令将 activedefrag 配置项设置为 yes 即可(默认关闭)。

config set activedefrag yes

具体什么时候清理需要通过下面两个参数控制:

# 内存碎片占用空间达到 500mb 的时候开始清理
config set active-defrag-ignore-bytes 500mb
# 内存碎片率大于 1.5 的时候开始清理
config set active-defrag-threshold-lower 50

通过 Redis 自动内存碎片清理机制可能会对 Redis 的性能产生影响,我们可以通过下面两个参数来减少对 Redis 性能的影响:

# 内存碎片清理所占用 CPU 时间的比例不低于 20%
config set active-defrag-cycle-min 20
# 内存碎片清理所占用 CPU 时间的比例不高于 50%
config set active-defrag-cycle-max 50

另外,重启节点可以做到内存碎片重新整理。如果你采用的是高可用架构的 Redis 集群的话,你可以将碎片率过高的主节点转换为从节点,以便进行安全重启。

Emoji Test
September 19, 2015 2,999 views
Emoji Test

This is an emoji test. :smile: lol.

See emoji cheat sheet for more detail :wink: : https://www.webpagefx.com/tools/emoji-cheat-sheet/.

:bowtie::smile::laughing::blush::smiley::relaxed::smirk: :heart_eyes::kissing_heart::kissing_closed_eyes::flushed::relieved::satisfied::grin: