如何使用Elastic Stack在Ubuntu 18.04上分析管理的Redis数据库统计信息

作者选择了自由开源基金作为为捐赠而写计划的一部分来接受捐赠。

介绍

数据库监控是持续的系统跟踪各种指标的过程,这些指标显示数据库的性能如何。通过观察性能数据,您可以获得宝贵的见解,并识别可能的瓶颈,以及找到改善数据库性能的其他方法。这种系统通常实现了警报功能,当事情出错时通知管理员。收集的统计数据不仅可以用于改进数据库的配置和工作流程,还可以用于客户端应用程序的配置和工作流程。

使用Elastic Stack(ELK Stack)监视您的托管数据库的好处在于其对搜索的出色支持以及快速摄入新数据的能力。它在更新数据方面并不突出,但这种权衡对于监视和日志记录目的来说是可以接受的,因为过去的数据几乎不会更改。Elasticsearch提供了强大的查询数据的方式,您可以通过Kibana使用它来更好地了解数据库在不同时间段内的表现。这将使您能够将数据库负载与现实事件相关联,以深入了解数据库的使用情况。

在本教程中,您将通过Logstash将由Redis INFO命令生成的数据库指标导入Elasticsearch。这涉及配置Logstash定期运行该命令,解析其输出,并立即将其发送到Elasticsearch以进行索引。导入的数据稍后可以在Kibana中进行分析和可视化。在教程结束时,您将拥有一个自动化系统,用于提取Redis统计信息以供后续分析。

先决条件

步骤 1 — 安装和配置 Logstash

在这一部分,您将安装 Logstash 并配置它从您的 Redis 数据库集群中提取统计信息,然后解析这些信息以发送到 Elasticsearch 进行索引。

首先使用以下命令安装 Logstash:

  1. sudo apt install logstash -y

安装 Logstash 后,启用服务以在启动时自动启动:

  1. sudo systemctl enable logstash

在配置 Logstash 以提取统计信息之前,让我们先看一下数据本身的样子。要连接到您的 Redis 数据库,请转到您的托管数据库控制面板,在连接详细信息面板下,从下拉菜单中选择标志

将显示一个预配置的命令用于 Redli 客户端,您将使用该命令连接到您的数据库。单击 复制,并在您的服务器上运行以下命令,将 redli_flags_command 替换为您刚刚复制的命令:

  1. redli_flags_command info

由于此命令的输出较长,我们将其分解为不同的部分进行解释。

在 Redis info 命令的输出中,各个部分都用 # 标记,表示注释。值以 key:value 的形式填充,这使得它们相对容易解析。

Server 部分包含有关 Redis 构建的技术信息,如其版本和基于的 Git 提交,而 Clients 部分提供了当前打开连接的数量。

Output
# Server redis_version:6.2.6 redis_git_sha1:4f4e829a redis_git_dirty:1 redis_build_id:5861572cb79aebf3 redis_mode:standalone os:Linux 5.11.12-300.fc34.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:11.2.1 process_id:79 process_supervised:systemd run_id:b8a0aa25d8f49a879112a04a817ac2acd92e0c75 tcp_port:25060 server_time_usec:1640878632737564 uptime_in_seconds:1679 uptime_in_days:0 hz:10 configured_hz:10 lru_clock:13488680 executable:/usr/bin/redis-server config_file:/etc/redis.conf io_threads_active:0 # Clients connected_clients:4 cluster_connections:0 maxclients:10032 client_recent_max_input_buffer:24 client_recent_max_output_buffer:0 ...

Memory 确认了 Redis 为自身分配了多少 RAM,以及它可能使用的最大内存量。如果内存开始不足,它将使用您在控制面板中指定的策略释放键(在此输出中显示在 maxmemory_policy 字段中)。

Output
... # Memory used_memory:977696 used_memory_human:954.78K used_memory_rss:9977856 used_memory_rss_human:9.52M used_memory_peak:977696 used_memory_peak_human:954.78K used_memory_peak_perc:100.00% used_memory_overhead:871632 used_memory_startup:810128 used_memory_dataset:106064 used_memory_dataset_perc:63.30% allocator_allocated:947216 allocator_active:1273856 allocator_resident:3510272 total_system_memory:1017667584 total_system_memory_human:970.52M 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:455081984 maxmemory_human:434.00M maxmemory_policy:noeviction allocator_frag_ratio:1.34 allocator_frag_bytes:326640 allocator_rss_ratio:2.76 allocator_rss_bytes:2236416 rss_overhead_ratio:2.84 rss_overhead_bytes:6467584 mem_fragmentation_ratio:11.43 mem_fragmentation_bytes:9104832 mem_not_counted_for_evict:0 mem_replication_backlog:0 mem_clients_slaves:0 mem_clients_normal:61504 mem_aof_buffer:0 mem_allocator:jemalloc-5.1.0 active_defrag_running:0 lazyfree_pending_objects:0 ...

Persistence 部分,您可以看到 Redis 上次保存存储在磁盘上的键的时间,以及是否成功。 Stats 部分提供了与客户端和集群连接相关的数字,请求的键被找到(或未找到)的次数等等。

Output
... # Persistence loading:0 current_cow_size:0 current_cow_size_age:0 current_fork_perc:0.00 current_save_keys_processed:0 current_save_keys_total:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1640876954 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:1 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:217088 aof_enabled:0 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:0 module_fork_in_progress:0 module_fork_last_cow_size:0 # Stats total_connections_received:202 total_commands_processed:2290 instantaneous_ops_per_sec:0 total_net_input_bytes:38034 total_net_output_bytes:1103968 instantaneous_input_kbps:0.01 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 expired_stale_perc:0.00 expired_time_cap_reached_count:0 expire_cycle_cpu_milliseconds:29 evicted_keys:0 keyspace_hits:0 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:452 total_forks:1 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_error_replies:0 dump_payload_sanitizations:0 total_reads_processed:2489 total_writes_processed:2290 io_threaded_reads_processed:0 io_threaded_writes_processed:0 ...

通过查看 Replication 下的 role,您可以知道自己是否连接到主节点还是副本节点。该部分的其余部分提供了当前连接的副本数量以及副本相对于主节点缺少的数据量。如果您连接到的实例是副本,则可能会有其他字段。

注意: Redis 项目在其文档和各种命令中使用“master”和“slave”这些术语。DigitalOcean 通常更喜欢使用替代术语“primary”和“replica”。本指南将尽可能默认使用“primary”和“replica”这些术语,但请注意,在某些情况下,“master”和“slave”这些术语不可避免地会出现。

Output
... # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:f727fad3691f2a8d8e593b087c468bbb83703af3 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:45088768 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 ...

CPU下,您将看到Redis当前正在消耗的系统(used_cpu_sys)和用户(used_cpu_user)CPU功率的数量。Cluster部分仅包含一个唯一字段,cluster_enabled,用于指示Redis集群正在运行。

Output
... # CPU used_cpu_sys:1.617986 used_cpu_user:1.248422 used_cpu_sys_children:0.000000 used_cpu_user_children:0.001459 used_cpu_sys_main_thread:1.567638 used_cpu_user_main_thread:1.218768 # Modules # 错误统计 # 集群 cluster_enabled:0 # Keyspace

Logstash将被指定定期在您的Redis数据库上运行info命令(类似于您刚刚执行的方式),解析结果,并将它们发送到Elasticsearch。然后,您将能够稍后从Kibana中访问它们。

您将在名为redis.conf的文件中存储将Redis统计信息索引到Elasticsearch的配置,该文件位于/etc/logstash/conf.d目录下,Logstash存储配置文件的位置。当作为服务启动时,它将自动在后台运行它们。

使用您喜欢的编辑器(例如nano)创建redis.conf

  1. sudo nano /etc/logstash/conf.d/redis.conf

添加以下行:

/etc/logstash/conf.d/redis.conf
input {
	exec {
		command => "redis_flags_command info"
		interval => 10
		type => "redis_info"
	}
}

filter {
	kv {
		value_split => ":"
		field_split => "\r\n"
		remove_field => [ "command", "message" ]
	}

	ruby {
		code =>
		"
		event.to_hash.keys.each { |k|
			if event.get(k).to_i.to_s == event.get(k) # is integer?
				event.set(k, event.get(k).to_i) # convert to integer
			end
			if event.get(k).to_f.to_s == event.get(k) # is float?
				event.set(k, event.get(k).to_f) # convert to float
			end
		}
		puts 'Ruby filter finished'
		"
	}
}

output {
    elasticsearch {
        hosts => "http://localhost:9200"
        index => "%{type}"
    }
}

记得将redis_flags_command替换为您在上一步中使用的控制面板中显示的命令。

您定义了一个input,它是一组将在收集到的数据上运行的过滤器,并且一个output将把经过筛选的数据发送到Elasticsearch。输入包括exec命令,它将会在服务器上周期性地运行一个command,在设定的时间间隔interval(以秒为单位)之后。它还指定了一个type参数,用于在Elasticsearch中索引时定义文档类型。exec块会传递一个包含两个字段的对象,commandmessage字符串。command字段将包含已运行的命令,而message将包含其输出。

从输入收集到的数据将按顺序经过两个过滤器的处理。kv过滤器代表键值过滤器,内置于Logstash中。它用于解析以keyvalue_separatorvalue一般形式格式化的数据,并提供了参数来指定哪些内容被认为是值和字段分隔符。字段分隔符涉及将以一般形式格式化的数据之间的字符串分隔开。在Redis INFO命令的输出中,字段分隔符(field_split)是一个换行符,值分隔符(value_split)是:。不符合定义形式的行将被丢弃,包括注释。

配置kv过滤器,将:传递给value_split参数,并将\r\n(表示换行)传递给field_split参数。您还要求将commandmessage字段从当前数据对象中移除,将它们作为数组元素传递给remove_field,因为它们包含了现在无用的数据。

kv过滤器将其解析的值表示为字符串(文本)类型。这引发了一个问题,因为Kibana无法轻松处理字符串类型,即使它实际上是一个数字。为了解决这个问题,您将使用自定义的Ruby代码将仅包含数字的字符串转换为数字(如果可能的话)。第二个过滤器是一个ruby块,提供一个接受包含要运行的代码的字符串的code参数。

event是Logstash提供给您代码的变量,包含过滤器管道中的当前数据。如前所述,过滤器依次运行,这意味着Ruby过滤器将接收来自kv过滤器的解析数据。Ruby代码本身将event转换为哈希,并遍历键,然后检查与键关联的值是否可以表示为整数或浮点数(带小数的数字)。如果可以,字符串值将被解析的数字替换。当循环结束时,它会打印出一条消息(Ruby filter finished)以报告进度。

输出将处理后的数据发送到Elasticsearch进行索引。生成的文档将存储在redis_info索引中,在输入中定义,并作为参数传递给输出块。

保存并关闭文件。

您已经使用apt安装了Logstash,并配置了它定期从Redis请求统计信息,处理并将其发送到您的Elasticsearch实例。

步骤2 — 测试Logstash配置

现在,您将通过运行Logstash来测试配置,以验证它是否能正确地拉取数据。

Logstash支持通过将其文件路径传递给-f参数来运行特定的配置。运行以下命令来测试您上一步的新配置:

  1. sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/redis.conf

可能需要一些时间才能显示输出,但很快您将看到类似以下的内容:

Output
Using bundled JDK: /usr/share/logstash/jdk OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console [INFO ] 2021-12-30 15:42:08.887 [main] runner - Starting Logstash {"logstash.version"=>"7.16.2", "jruby.version"=>"jruby 9.2.20.1 (2.5.8) 2021-11-30 2a2962fbd1 OpenJDK 64-Bit Server VM 11.0.13+8 on 11.0.13+8 +indy +jit [linux-x86_64]"} [INFO ] 2021-12-30 15:42:08.932 [main] settings - Creating directory {:setting=>"path.queue", :path=>"/usr/share/logstash/data/queue"} [INFO ] 2021-12-30 15:42:08.939 [main] settings - Creating directory {:setting=>"path.dead_letter_queue", :path=>"/usr/share/logstash/data/dead_letter_queue"} [WARN ] 2021-12-30 15:42:09.406 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified [INFO ] 2021-12-30 15:42:09.449 [LogStash::Runner] agent - No persistent UUID file found. Generating new UUID {:uuid=>"acc4c891-936b-4271-95de-7d41f4a41166", :path=>"/usr/share/logstash/data/uuid"} [INFO ] 2021-12-30 15:42:10.985 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600, :ssl_enabled=>false} [INFO ] 2021-12-30 15:42:11.601 [Converge PipelineAction::Create<main>] Reflections - Reflections took 77 ms to scan 1 urls, producing 119 keys and 417 values [WARN ] 2021-12-30 15:42:12.215 [Converge PipelineAction::Create<main>] plain - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode. [WARN ] 2021-12-30 15:42:12.366 [Converge PipelineAction::Create<main>] plain - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode. [WARN ] 2021-12-30 15:42:12.431 [Converge PipelineAction::Create<main>] elasticsearch - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode. [INFO ] 2021-12-30 15:42:12.494 [[main]-pipeline-manager] elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["http://localhost:9200"]} [INFO ] 2021-12-30 15:42:12.755 [[main]-pipeline-manager] elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://localhost:9200/]}} [WARN ] 2021-12-30 15:42:12.955 [[main]-pipeline-manager] elasticsearch - Restored connection to ES instance {:url=>"http://localhost:9200/"} [INFO ] 2021-12-30 15:42:12.967 [[main]-pipeline-manager] elasticsearch - Elasticsearch version determined (7.16.2) {:es_version=>7} [WARN ] 2021-12-30 15:42:12.968 [[main]-pipeline-manager] elasticsearch - Detected a 6.x and above cluster: the `type` event field won't be used to determine the document _type {:es_version=>7} [WARN ] 2021-12-30 15:42:13.065 [[main]-pipeline-manager] kv - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode. [INFO ] 2021-12-30 15:42:13.090 [Ruby-0-Thread-10: :1] elasticsearch - Using a default mapping template {:es_version=>7, :ecs_compatibility=>:disabled} [INFO ] 2021-12-30 15:42:13.147 [Ruby-0-Thread-10: :1] elasticsearch - Installing Elasticsearch template {:name=>"logstash"} [INFO ] 2021-12-30 15:42:13.192 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>2, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>250, "pipeline.sources"=>["/etc/logstash/conf.d/redis.conf"], :thread=>"#<Thread:0x5104e975 run>"} [INFO ] 2021-12-30 15:42:13.973 [[main]-pipeline-manager] javapipeline - Pipeline Java execution initialization time {"seconds"=>0.78} [INFO ] 2021-12-30 15:42:13.983 [[main]-pipeline-manager] exec - Registering Exec Input {:type=>"redis_info", :command=>"redli --tls -h db-redis-fra1-68603-do-user-1446234-0.b.db.ondigitalocean.com -a hnpJxAgoH3Om3UwM -p 25061 info", :interval=>10, :schedule=>nil} [INFO ] 2021-12-30 15:42:13.994 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"} [INFO ] 2021-12-30 15:42:14.034 [Agent thread] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]} Ruby filter finished Ruby filter finished Ruby filter finished ...

您将看到Ruby filter finished消息定期打印出来(在上一步中设置为10秒),这意味着统计信息正在被发送到Elasticsearch。

您可以通过在键盘上按CTRL + C退出Logstash。如前所述,当作为服务启动时,Logstash会自动在/etc/logstash/conf.d下找到的所有配置文件后台运行。运行以下命令来启动它:

  1. sudo systemctl start logstash

你已经运行了Logstash来检查它是否能连接到你的Redis集群并收集数据。接下来,你将在Kibana中探索一些统计数据。

步骤3 — 在Kibana中探索导入的数据

在这一部分中,你将探索并可视化描述你的数据库性能的统计数据。

在你的网络浏览器中,导航到你的域名,在其中你已经将Kibana暴露为先决条件的一部分。你将看到默认的欢迎页面:

在探索Logstash发送到Elasticsearch的数据之前,你首先需要将redis_info索引添加到Kibana中。为此,请首先从欢迎页面中选择自行探索,然后打开左上角的汉堡菜单。在分析下,点击发现

Kibana然后会提示你创建一个新的索引模式:

点击创建索引模式。你将看到一个创建新索引模式的表单。Kibana中的索引模式提供了一种从多个Elasticsearch索引中同时拉取数据的方式,并且可以用于仅探索一个索引。

在右侧,Kibana 列出了所有可用的索引,比如您已配置 Logstash 使用的 redis_info。在名称文本字段中键入它,并从下拉菜单中选择@timestamp作为时间戳字段。完成后,点击下方的创建索引模式按钮。

要创建和查看现有的可视化,请打开汉堡菜单。在分析下,选择仪表盘。加载完成后,点击创建可视化开始创建新的可视化:

左侧面板提供了 Kibana 可用于绘制可视化的值列表,它们将显示在屏幕中央部分。在屏幕右上角是日期范围选择器。如果可视化中使用了@timestamp字段,则 Kibana 只会显示在范围选择器中指定的时间间隔内的数据。

在页面的主要部分的下拉菜单中,选择线条线条和区域部分下。然后,从左侧列表中找到used_memory字段并将其拖动到中央部分。您很快将看到一个关于使用内存中位数的时间线可视化:

在右侧,您可以配置水平和垂直轴的处理方式。在那里,您可以通过点击显示的轴将垂直轴设置为显示平均值,而不是中位数:

您可以选择不同的函数,或提供自己的函数:

图表将立即使用更新后的值进行刷新。

在这一步中,您使用Kibana可视化了您管理的Redis数据库的内存使用情况。这将帮助您更好地了解数据库的使用情况,从而帮助您优化客户端应用程序以及数据库本身。

结论

您现在已经在服务器上安装了Elastic Stack,并配置为定期从您管理的Redis数据库中提取统计数据。您可以使用Kibana或其他适当的软件分析和可视化数据,这将帮助您收集有关数据库性能的宝贵见解和现实世界的相关性。

有关您可以使用Redis托管数据库做什么的更多信息,请访问产品文档。如果您想使用其他可视化类型呈现数据库统计信息,请查看Kibana文档获取进一步的说明。

Source:
https://www.digitalocean.com/community/tutorials/how-to-analyze-managed-redis-database-statistics-using-the-elastic-stack-on-ubuntu-18-04