作者选择了自由开源基金作为为捐赠而写计划的一部分来接受捐赠。
介绍
数据库监控是持续的系统跟踪各种指标的过程,这些指标显示数据库的性能如何。通过观察性能数据,您可以获得宝贵的见解,并识别可能的瓶颈,以及找到改善数据库性能的其他方法。这种系统通常实现了警报功能,当事情出错时通知管理员。收集的统计数据不仅可以用于改进数据库的配置和工作流程,还可以用于客户端应用程序的配置和工作流程。
使用Elastic Stack(ELK Stack)监视您的托管数据库的好处在于其对搜索的出色支持以及快速摄入新数据的能力。它在更新数据方面并不突出,但这种权衡对于监视和日志记录目的来说是可以接受的,因为过去的数据几乎不会更改。Elasticsearch提供了强大的查询数据的方式,您可以通过Kibana使用它来更好地了解数据库在不同时间段内的表现。这将使您能够将数据库负载与现实事件相关联,以深入了解数据库的使用情况。
在本教程中,您将通过Logstash将由Redis INFO命令生成的数据库指标导入Elasticsearch。这涉及配置Logstash定期运行该命令,解析其输出,并立即将其发送到Elasticsearch以进行索引。导入的数据稍后可以在Kibana中进行分析和可视化。在教程结束时,您将拥有一个自动化系统,用于提取Redis统计信息以供后续分析。
先决条件
- 一台装有至少8 GB RAM、root权限和次要非root账户的Ubuntu 18.04服务器。您可以按照这个初始服务器设置指南进行设置。在本教程中,非root用户是
sammy
。 - 您的服务器上安装了Java 8。有关安装说明,请访问在Ubuntu 18.04上使用
apt
安装Java的方法,并按照第一步中概述的命令进行操作。您不需要安装Java开发工具包(JDK)。 - 您的服务器上安装了Nginx。有关操作指南,请参阅在Ubuntu 18.04上安装Nginx的方法教程。
- 您的服务器上安装了Elasticsearch和Kibana。完成在Ubuntu 18.04上安装Elasticsearch、Logstash和Kibana(Elastic Stack)教程的前两步。
- A Redis managed database provisioned from DigitalOcean with connection information available. Make sure that your server’s IP address is on the whitelist. For a guide on creating a Redis database using the DigitalOcean Control Panel, visit the Redis Quickstart guide.
- Redli根据在Ubuntu 18.04上连接到托管数据库的方法教程安装在您的服务器上。
步骤 1 — 安装和配置 Logstash
在这一部分,您将安装 Logstash 并配置它从您的 Redis 数据库集群中提取统计信息,然后解析这些信息以发送到 Elasticsearch 进行索引。
首先使用以下命令安装 Logstash:
安装 Logstash 后,启用服务以在启动时自动启动:
在配置 Logstash 以提取统计信息之前,让我们先看一下数据本身的样子。要连接到您的 Redis 数据库,请转到您的托管数据库控制面板,在连接详细信息面板下,从下拉菜单中选择标志:
将显示一个预配置的命令用于 Redli 客户端,您将使用该命令连接到您的数据库。单击 复制,并在您的服务器上运行以下命令,将 redli_flags_command
替换为您刚刚复制的命令:
由于此命令的输出较长,我们将其分解为不同的部分进行解释。
在 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
:
添加以下行:
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
块会传递一个包含两个字段的对象,command
和message
字符串。command
字段将包含已运行的命令,而message
将包含其输出。
从输入收集到的数据将按顺序经过两个过滤器的处理。kv
过滤器代表键值过滤器,内置于Logstash中。它用于解析以keyvalue_separatorvalue
一般形式格式化的数据,并提供了参数来指定哪些内容被认为是值和字段分隔符。字段分隔符涉及将以一般形式格式化的数据之间的字符串分隔开。在Redis INFO命令的输出中,字段分隔符(field_split
)是一个换行符,值分隔符(value_split
)是:
。不符合定义形式的行将被丢弃,包括注释。
配置kv
过滤器,将:
传递给value_split
参数,并将\r\n
(表示换行)传递给field_split
参数。您还要求将command
和message
字段从当前数据对象中移除,将它们作为数组元素传递给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
参数来运行特定的配置。运行以下命令来测试您上一步的新配置:
可能需要一些时间才能显示输出,但很快您将看到类似以下的内容:
OutputUsing 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
下找到的所有配置文件后台运行。运行以下命令来启动它:
你已经运行了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文档获取进一步的说明。