Redis服务器内存增长到一定的使用率阀值,需要分析内存的使用情况,查找出过大的key
阿里云提供两种方案:
全量分析使用方案2,导出memory.csv之后,后续通过把数据导入到MySQL中,同时对key按分隔符进行拆分,以做查询分析:
1、创建表
CREATE TABLE `memory` (
`database` INT(11) NULL DEFAULT NULL,
`type` VARCHAR(128) NULL DEFAULT NULL,
`key` VARCHAR(128) NULL DEFAULT NULL,
`size_in_bytes` INT(11) NULL DEFAULT NULL,
`encoding` VARCHAR(128) NULL DEFAULT NULL,
`num_elements` INT(11) NULL DEFAULT NULL,
`len_largest_element` VARCHAR(128) NULL DEFAULT NULL,
`key1` VARCHAR(100) NULL DEFAULT NULL,
`key2` VARCHAR(100) NULL DEFAULT NULL,
`key3` VARCHAR(100) NULL DEFAULT NULL,
INDEX `size_in_bytes` (`size_in_bytes`),
INDEX `num_elements` (`num_elements`),
INDEX `key1` (`key1`),
INDEX `key2` (`key2`),
INDEX `key3` (`key3`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
2、导入数据(注意,路径中不允许包含中文!)
3、创建一个MySQL的SPLIT函数,如:MySQL Split 函数
4、对key按分隔符进行拆分:
update memory set key1 = SPLIT_STR(`key`, ':', 1), key2 = SPLIT_STR(`key`, ':', 2), key3 = SPLIT_STR(`key`, ':', 3)
5、执行查询进行分析:
select key1, sum(size_in_bytes) size, sum(num_elements) num from memory group by key1 order by size desc, num desc
select key1, key2 , sum(size_in_bytes) size, sum(num_elements) num from memory group by key1, key2 order by size desc, num desc
如果redis的数据量较大,导入mysql的速度就会很慢,可以把导入mysql换成导入MaxCompute来做分析:
1、在MaxCompute中创建原始数据表redis_data和分析表redis:
CREATE TABLE IF NOT EXISTS `exe`.`redis_data` ( `db` BIGINT , `type` STRING, `key` STRING, `size_in_bytes` BIGINT, `encoding` STRING, `num_elements` BIGINT, `len_largest_element` STRING);
CREATE TABLE IF NOT EXISTS `exe`.`redis` ( `db` BIGINT, `type` STRING, `key` STRING, `size_in_bytes` BIGINT, `encoding` STRING, `num_elements` BIGINT, `len_largest_element` STRING, `key1` STRING, `key2` STRING, `key3` STRING);
2、通过csv文件导入数据:
3、执行临时查询,通过MaxCompute的并行计算任务,把原始数据表redis_data对key按分隔符进行拆分,导入到分析表redis:
INSERT OVERWRITE TABLE redis SELECT db, `type`, `key`, size_in_bytes, encoding, num_elements, len_largest_element ,SPLIT_PART(`key`, ':', 1) AS key1 ,SPLIT_PART(`key`, ':', 2) AS key2 ,SPLIT_PART(`key`, ':', 3) AS key3 FROM redis_data
4、执行查询进行分析:
SELECT key1,SUM(size_in_bytes) AS `SIZE` ,SUM(num_elements) num FROM redis GROUP BY key1 ORDER BY `SIZE` DESC ,num DESC LIMIT 1000
SELECT key1 ,key2 ,SUM(size_in_bytes) AS `SIZE` ,SUM(num_elements) num FROM redis GROUP BY key1 ,key2 ORDER BY `SIZE` DESC ,num DESCLIMIT 1000
三、同时,集群版的Redis,在设置云监控时,需要注意:
需要设置资源范围为全部资源,来分别对各个节点的内存使用率进行监控和报警
否则,当其中一个节点因为一个大key而导致内存使用达到maxmemory,整个集群可能并不会报警
我们曾经发生过一次生产环境事故,个别Redis写入请求报达到maxmemory无法写入的异常,经查找发现8台Node中,有其中1台的内存使用率达到了100%,原因是开发人员一个list类型的key中记录了非常大的数据,导致单个key的内存使用量非常大(单个key只能放在一台Node中),但集群版的Redis内存使用率没有报警,原因就是需要做如上的云监控设置。