面试题答案
一键面试1. SDS的数据结构特点与数据篡改防范
- 空间预分配:
- SDS在需要对字符串进行扩展时,会额外分配未使用的空间。例如,如果要将SDS字符串长度从
len
扩展到newlen
,且newlen
小于1MB,Redis会分配newlen
+newlen
长度的空间(即除了满足当前所需的newlen
长度外,额外再分配newlen
长度的未使用空间);若newlen
大于等于1MB,则额外分配1MB空间。这种机制使得恶意用户难以通过简单的追加操作来覆盖相邻内存区域的数据,因为即使恶意篡改增加了数据长度,也会在预分配空间内进行,不会立即影响到其他重要数据。 - 例如,原本SDS存储字符串“hello”,长度
len
为5,若恶意用户试图通过追加内容篡改数据,在合理范围内(如小于1MB时按上述规则分配),Redis会按空间预分配规则进行空间调整,避免影响相邻数据。
- SDS在需要对字符串进行扩展时,会额外分配未使用的空间。例如,如果要将SDS字符串长度从
- 记录长度信息:
- SDS结构中明确记录了当前字符串的长度
len
。这使得在读取或操作SDS数据时,Redis能够准确知道数据的边界。恶意用户无法通过简单修改字符串内容使其超出实际分配空间而不被发现,因为Redis会根据len
来判断数据是否合法。例如,在进行字符串拼接操作时,Redis会依据len
判断拼接后的数据是否在分配的空间内,若超出则会重新分配空间,而不是任由恶意篡改的数据破坏内存结构。
- SDS结构中明确记录了当前字符串的长度
2. SDS内存管理机制与数据篡改防范
- 内存分配与释放的原子性:
- Redis使用的内存分配器(如jemalloc)在分配和释放内存时具有原子性。这意味着恶意用户很难通过并发操作来干扰内存分配与释放过程,从而篡改数据。当一个恶意操作试图在内存分配或释放过程中进行干扰时,由于原子操作的特性,内存分配器会确保操作要么完整执行,要么根本不执行,不会出现部分篡改的情况。例如,在多线程环境下,若恶意线程试图在SDS内存释放时修改内存指针,由于内存释放操作的原子性,该恶意操作不会生效,保证了数据的完整性。
- 内存重分配的安全性:
- 当SDS需要进行内存重分配时,Redis采用了安全的重分配策略。在扩展SDS空间时,会先分配足够的新空间,然后将原数据复制到新空间,最后释放原空间。在收缩SDS空间时,同样会先处理好数据,再进行空间释放。这使得恶意用户难以利用内存重分配过程中的漏洞来篡改数据。比如,恶意用户试图在内存复制过程中修改数据,但由于Redis是先完成数据复制再释放原空间,即使在复制过程中数据被恶意修改,原数据依然存在,不会导致数据丢失或被篡改后无法恢复,保证了数据的安全性。