影响 Redis 性能的操作有哪些? 面试者好软(www.haoruan.net)小弟听到这题后,窃喜,这题简单,不假思索地回答:使用 bigkey 会影响 Redis 的性能。 面试官面无表情的说道:还有吗? 好软(www.haoruan.net)小弟支支吾吾的没有答上来。 面试官继续说:
第一个:集合全量查询和聚合操作。因为它们的操作复杂度为O(N),例如集合元素的全量查询操作 HGETALL、SMEMBERS、以及集合的聚合统计操作,例如求交、并、差集。
第二个:bigkey 删除操作。因为删除操作的本质是要释放键值对占用的内存空间。在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,另外会阻塞当前释放内存的应用程序。如果一下子释放了大量内存,插入空闲内存块链表的操作时间就会增加,相应地就会造成 Redis 主线程的阻塞。
第三个:清空数据库。在 Redis 清空数据库时,比如 FLUSHDB 和 FLUSHALL 操作,涉及到删除和释放所有的键值对。
第四个:AOF 日志同步写。如果有大量的写操作需要记录在 AOF 日中中,并同步写回的话,就会阻塞主线程了。
第五个:加载 RDB 文件。在主从集群中,主库需要生成 RDB 文件,并传输给从库,创建和传输 RDB 文件时,不会阻塞主线程。但是从库在接收了 RDB 文件后,需要使用 FLUSHDB 命令清空当前数据库,清空后还需要把 RDB 文件加载到内存,RDB 文件越大,加载过程越慢。
面试者好软(www.haoruan.net)小弟听完后仰望着面试官,小声地嘀咕着,上述 5 个问题可有应对方案?
面试官面露微笑的说到:
bigkey 删除、清空数据库、AOF 日志同步写不属于关键路径操作,可以使用异步子线程机制来完成。Redis 在运行时会创建 3 个子线程、主线程会通过一个任务队列和三个子线程进行交互。子线程会根据任务的具体类型来执行相应的异步操作。
而对于集合全量查询和聚合操作,可以使用 SCAN 命令,分批读取数据,再在客户端进行聚合计算。
而对于从库加载 RDB 文件,则可以通过控制主库的数据量大小,比如 2 到 4 GB,来保证 RDB 文件能以较快的速度加载。 好软(www.haoruan.net)小弟听完后,叹了一口气,今天又是被面试官吊打的一天。