summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2017-09-20 22:09:10 +0200
committerGitHub <noreply@github.com>2017-09-20 22:09:10 +0200
commit3a387cb98ecd1bbcdef7e6d3bf0c3c8e58cab751 (patch)
tree7a9b39625444d1e70c8fb399836a308647e289bb /searchcore
parentaaf3e48ef7510d901e078357e15f700494942139 (diff)
parent07875f4607dfa88f174f1595a47d0c612e40a599 (diff)
Merge pull request #3459 from vespa-engine/geirst/fix-disk-and-memory-usage-sampling-for-docker
Geirst/fix disk and memory usage sampling for docker
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/attribute/attributeflush_test.cpp4
-rw-r--r--searchcore/src/tests/proton/common/hw_info_sampler/hw_info_sampler_test.cpp34
-rw-r--r--searchcore/src/tests/proton/server/disk_mem_usage_filter/disk_mem_usage_filter_test.cpp12
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt1
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/hw_info.h19
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.cpp69
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.h31
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.cpp53
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.h18
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp55
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.h29
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.cpp25
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/resource_usage_explorer.cpp11
13 files changed, 235 insertions, 126 deletions
diff --git a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
index ecb39af61bc..a2ffcda094b 100644
--- a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
@@ -606,8 +606,8 @@ Test::requireThatFlushedAttributeCanBeLoaded(const HwInfo &hwInfo)
void
Test::requireThatFlushedAttributeCanBeLoaded()
{
- TEST_DO(requireThatFlushedAttributeCanBeLoaded(HwInfo(false)));
- TEST_DO(requireThatFlushedAttributeCanBeLoaded(HwInfo(true)));
+ TEST_DO(requireThatFlushedAttributeCanBeLoaded(HwInfo(0, false, 0)));
+ TEST_DO(requireThatFlushedAttributeCanBeLoaded(HwInfo(0, true, 0)));
}
int
diff --git a/searchcore/src/tests/proton/common/hw_info_sampler/hw_info_sampler_test.cpp b/searchcore/src/tests/proton/common/hw_info_sampler/hw_info_sampler_test.cpp
index f9745d7fd03..3fd2802f059 100644
--- a/searchcore/src/tests/proton/common/hw_info_sampler/hw_info_sampler_test.cpp
+++ b/searchcore/src/tests/proton/common/hw_info_sampler/hw_info_sampler_test.cpp
@@ -44,7 +44,7 @@ struct Fixture
TEST_F("Test that hw_info_sampler uses override info", Fixture)
{
- Config samplerCfg(75.0, 100.0, sampleLen);
+ Config samplerCfg(0, 75.0, 100.0, sampleLen, 0);
HwInfoSampler sampler(test_dir, samplerCfg);
EXPECT_EQUAL(75.0, sampler.diskWriteSpeed());
EXPECT_NOT_EQUAL(0, time_point_to_long(sampler.sampleTime()));
@@ -57,7 +57,7 @@ TEST_F("Test that hw_info_sampler uses saved info", Fixture)
builder.disk.writespeed = 72.0;
builder.disk.sampletime = time_point_to_long(Clock::now());
f.writeConfig(builder);
- Config samplerCfg(0.0, 70.0, sampleLen);
+ Config samplerCfg(0, 0.0, 70.0, sampleLen, 0);
HwInfoSampler sampler(test_dir, samplerCfg);
EXPECT_EQUAL(builder.disk.writespeed, sampler.diskWriteSpeed());
EXPECT_EQUAL(builder.disk.sampletime, time_point_to_long(sampler.sampleTime()));
@@ -66,7 +66,7 @@ TEST_F("Test that hw_info_sampler uses saved info", Fixture)
TEST_F("Test that hw_info_sampler can sample disk write speed", Fixture)
{
- Config samplerCfg(0.0, 100.0, sampleLen);
+ Config samplerCfg(0, 0.0, 100.0, sampleLen, 0);
HwInfoSampler sampler(test_dir, samplerCfg);
ASSERT_NOT_EQUAL(0.0, sampler.diskWriteSpeed());
ASSERT_NOT_EQUAL(0, time_point_to_long(sampler.sampleTime()));
@@ -76,6 +76,34 @@ TEST_F("Test that hw_info_sampler can sample disk write speed", Fixture)
time_point_to_long(sampler2.sampleTime()));
}
+TEST_F("require that disk size can be specified", Fixture)
+{
+ Config samplerCfg(1024, 1.0, 0.0, sampleLen, 0);
+ HwInfoSampler sampler(test_dir, samplerCfg);
+ EXPECT_EQUAL(1024u, sampler.hwInfo().diskSizeBytes());
+}
+
+TEST_F("require that disk size can be sampled", Fixture)
+{
+ Config samplerCfg(0, 1.0, 0.0, sampleLen, 0);
+ HwInfoSampler sampler(test_dir, samplerCfg);
+ EXPECT_GREATER(sampler.hwInfo().diskSizeBytes(), 0u);
+}
+
+TEST_F("require that memory size can be specified", Fixture)
+{
+ Config samplerCfg(0, 1.0, 0.0, sampleLen, 1024);
+ HwInfoSampler sampler(test_dir, samplerCfg);
+ EXPECT_EQUAL(1024u, sampler.hwInfo().memorySizeBytes());
+}
+
+TEST_F("require that memory size can be sampled", Fixture)
+{
+ Config samplerCfg(0, 1.0, 0.0, sampleLen, 0);
+ HwInfoSampler sampler(test_dir, samplerCfg);
+ EXPECT_GREATER(sampler.hwInfo().memorySizeBytes(), 0u);
+}
+
TEST_MAIN()
{
vespalib::rmdir(test_dir, true);
diff --git a/searchcore/src/tests/proton/server/disk_mem_usage_filter/disk_mem_usage_filter_test.cpp b/searchcore/src/tests/proton/server/disk_mem_usage_filter/disk_mem_usage_filter_test.cpp
index 5d8a647f675..05d53c0bf18 100644
--- a/searchcore/src/tests/proton/server/disk_mem_usage_filter/disk_mem_usage_filter_test.cpp
+++ b/searchcore/src/tests/proton/server/disk_mem_usage_filter/disk_mem_usage_filter_test.cpp
@@ -1,9 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/searchcore/proton/common/hw_info.h>
#include <vespa/searchcore/proton/server/disk_mem_usage_filter.h>
using proton::DiskMemUsageFilter;
+using proton::HwInfo;
namespace fs = std::experimental::filesystem;
@@ -16,9 +18,9 @@ struct Fixture
using Config = DiskMemUsageFilter::Config;
Fixture()
- : _filter(64 * 1024 * 1024)
+ : _filter(HwInfo(100, false, 64 * 1024 * 1024))
{
- _filter.setDiskStats({.capacity = 100, .free = 100, .available=100});
+ _filter.setDiskStats(0);
_filter.setMemoryStats(vespalib::ProcessMemoryStats(10000000,
10000001,
10000002,
@@ -41,7 +43,7 @@ struct Fixture
}
void triggerDiskLimit() {
- _filter.setDiskStats({.capacity = 100, .free = 20, .available=10});
+ _filter.setDiskStats(90);
}
void triggerMemoryLimit()
@@ -76,7 +78,7 @@ TEST_F("Check that disk limit can be reached", Fixture)
"action: \"add more content nodes\", "
"reason: \"disk used (0.9) > disk limit (0.8)\", "
"stats: { "
- "capacity: 100, free: 20, available: 10, diskUsed: 0.9, diskLimit: 0.8}}");
+ "capacity: 100, used: 90, diskUsed: 0.9, diskLimit: 0.8}}");
}
TEST_F("Check that memory limit can be reached", Fixture)
@@ -108,7 +110,7 @@ TEST_F("Check that both disk limit and memory limit can be reached", Fixture)
"action: \"add more content nodes\", "
"reason: \"disk used (0.9) > disk limit (0.8)\", "
"stats: { "
- "capacity: 100, free: 20, available: 10, diskUsed: 0.9, diskLimit: 0.8}}");
+ "capacity: 100, used: 90, diskUsed: 0.9, diskLimit: 0.8}}");
}
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
index dec686d3070..cdca446f114 100644
--- a/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
+++ b/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
@@ -22,4 +22,5 @@ vespa_add_library(searchcore_pcommon STATIC
DEPENDS
searchcore_proton_metrics
searchcore_fconfig
+ stdc++fs
)
diff --git a/searchcore/src/vespa/searchcore/proton/common/hw_info.h b/searchcore/src/vespa/searchcore/proton/common/hw_info.h
index 06efaec18f2..e98af734ba3 100644
--- a/searchcore/src/vespa/searchcore/proton/common/hw_info.h
+++ b/searchcore/src/vespa/searchcore/proton/common/hw_info.h
@@ -2,6 +2,8 @@
#pragma once
+#include <cstdint>
+
namespace proton {
/*
@@ -9,19 +11,30 @@ namespace proton {
*/
class HwInfo
{
+ uint64_t _diskSizeBytes;
bool _slowDisk;
+ uint64_t _memorySizeBytes;
+
public:
HwInfo()
- : _slowDisk(false)
+ : _diskSizeBytes(0),
+ _slowDisk(false),
+ _memorySizeBytes(0)
{
}
- HwInfo(bool slowDisk_in)
- : _slowDisk(slowDisk_in)
+ HwInfo(uint64_t diskSizeBytes_in,
+ bool slowDisk_in,
+ uint64_t memorySizeBytes_in)
+ : _diskSizeBytes(diskSizeBytes_in),
+ _slowDisk(slowDisk_in),
+ _memorySizeBytes(memorySizeBytes_in)
{
}
+ uint64_t diskSizeBytes() const { return _diskSizeBytes; }
bool slowDisk() const { return _slowDisk; }
+ uint64_t memorySizeBytes() const { return _memorySizeBytes; }
};
}
diff --git a/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.cpp b/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.cpp
index 73bb20c712a..0d5839e9bec 100644
--- a/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.cpp
@@ -1,13 +1,14 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "hw_info_sampler.h"
-#include <vespa/config/config.h>
#include <vespa/config/common/configholder.h>
+#include <vespa/config/config.h>
#include <vespa/config/file/filesource.h>
-#include <vespa/searchcore/config/config-hwinfo.h>
#include <vespa/config/print/fileconfigwriter.h>
-#include <vespa/vespalib/io/fileutil.h>
#include <vespa/fastos/file.h>
+#include <vespa/searchcore/config/config-hwinfo.h>
+#include <vespa/vespalib/io/fileutil.h>
+#include <experimental/filesystem>
using config::ConfigHandle;
using config::ConfigSubscriber;
@@ -22,6 +23,26 @@ namespace proton {
namespace {
+uint64_t
+sampleDiskSizeBytes(const std::string &pathStr, const HwInfoSampler::Config &cfg)
+{
+ if (cfg.diskSizeBytes != 0) {
+ return cfg.diskSizeBytes;
+ }
+ std::experimental::filesystem::path path(pathStr);
+ auto space_info = std::experimental::filesystem::space(path);
+ return space_info.capacity;
+}
+
+uint64_t
+sampleMemorySizeBytes(const HwInfoSampler::Config &cfg)
+{
+ if (cfg.memorySizeBytes != 0) {
+ return cfg.memorySizeBytes;
+ }
+ return sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
+}
+
std::unique_ptr<HwinfoConfig> readConfig(const vespalib::string &path) {
FileSpec spec(path + "/" + "hwinfo.cfg");
ConfigSubscriber s(spec);
@@ -78,20 +99,11 @@ HwInfoSampler::HwInfoSampler(const vespalib::string &path,
const Config &config)
: _hwInfo(),
_sampleTime(),
- _diskWriteSpeed(0.0)
+ _diskSizeBytes(sampleDiskSizeBytes(path, config)),
+ _diskWriteSpeed(0.0),
+ _memorySizeBytes(sampleMemorySizeBytes(config))
{
- if (config._diskWriteSpeedOverride != 0) {
- _diskWriteSpeed = config._diskWriteSpeedOverride;
- _sampleTime = Clock::now();
- } else {
- auto cfg = readConfig(path);
- if (cfg && cfg->disk.sampletime != 0.0) {
- _sampleTime = std::chrono::time_point<Clock>(std::chrono::seconds(cfg->disk.sampletime));
- _diskWriteSpeed = cfg->disk.writespeed;
- } else {
- sample(path, config);
- }
- }
+ setDiskWriteSpeed(path, config);
setup(config);
}
@@ -102,15 +114,32 @@ HwInfoSampler::~HwInfoSampler()
void
HwInfoSampler::setup(const Config &config)
{
- bool slowDisk = _diskWriteSpeed < config._slowWriteSpeedLimit;
- _hwInfo = HwInfo(slowDisk);
+ bool slowDisk = _diskWriteSpeed < config.slowWriteSpeedLimit;
+ _hwInfo = HwInfo(_diskSizeBytes, slowDisk, _memorySizeBytes);
+}
+
+void
+HwInfoSampler::setDiskWriteSpeed(const vespalib::string &path, const Config &config)
+{
+ if (config.diskWriteSpeedOverride != 0) {
+ _diskWriteSpeed = config.diskWriteSpeedOverride;
+ _sampleTime = Clock::now();
+ } else {
+ auto cfg = readConfig(path);
+ if (cfg && cfg->disk.sampletime != 0.0) {
+ _sampleTime = std::chrono::time_point<Clock>(std::chrono::seconds(cfg->disk.sampletime));
+ _diskWriteSpeed = cfg->disk.writespeed;
+ } else {
+ sampleDiskWriteSpeed(path, config);
+ }
+ }
}
void
-HwInfoSampler::sample(const vespalib::string &path, const Config &config)
+HwInfoSampler::sampleDiskWriteSpeed(const vespalib::string &path, const Config &config)
{
size_t minDiskWriteLen = 1024u * 1024u;
- size_t diskWriteLen = config._diskSampleWriteSize;
+ size_t diskWriteLen = config.diskSampleWriteSize;
diskWriteLen = std::max(diskWriteLen, minDiskWriteLen);
_sampleTime = Clock::now();
_diskWriteSpeed = measureDiskWriteSpeed(path, diskWriteLen);
diff --git a/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.h b/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.h
index 22af2d32786..208dac0ee44 100644
--- a/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.h
+++ b/searchcore/src/vespa/searchcore/proton/common/hw_info_sampler.h
@@ -16,16 +16,22 @@ class HwInfoSampler
{
public:
struct Config {
- double _diskWriteSpeedOverride;
- double _slowWriteSpeedLimit;
- uint64_t _diskSampleWriteSize;
-
- Config(double diskWriteSpeedOverride,
- double slowWriteSpeedLimit,
- double diskSampleWriteSize)
- : _diskWriteSpeedOverride(diskWriteSpeedOverride),
- _slowWriteSpeedLimit(slowWriteSpeedLimit),
- _diskSampleWriteSize(diskSampleWriteSize)
+ uint64_t diskSizeBytes;
+ double diskWriteSpeedOverride;
+ double slowWriteSpeedLimit;
+ uint64_t diskSampleWriteSize;
+ uint64_t memorySizeBytes;
+
+ Config(uint64_t diskSizeBytes_,
+ double diskWriteSpeedOverride_,
+ double slowWriteSpeedLimit_,
+ double diskSampleWriteSize_,
+ uint64_t memorySizeBytes_)
+ : diskSizeBytes(diskSizeBytes_),
+ diskWriteSpeedOverride(diskWriteSpeedOverride_),
+ slowWriteSpeedLimit(slowWriteSpeedLimit_),
+ diskSampleWriteSize(diskSampleWriteSize_),
+ memorySizeBytes(memorySizeBytes_)
{
}
};
@@ -34,10 +40,13 @@ private:
HwInfo _hwInfo;
using Clock = std::chrono::system_clock;
Clock::time_point _sampleTime;
+ uint64_t _diskSizeBytes;
double _diskWriteSpeed;
+ uint64_t _memorySizeBytes;
void setup(const Config &config);
- void sample(const vespalib::string &path, const Config &config);
+ void setDiskWriteSpeed(const vespalib::string &path, const Config &config);
+ void sampleDiskWriteSpeed(const vespalib::string &path, const Config &config);
public:
HwInfoSampler(const vespalib::string &path, const Config &config);
~HwInfoSampler();
diff --git a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.cpp b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.cpp
index d489f477df2..307eed94095 100644
--- a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.cpp
@@ -3,6 +3,7 @@
#include "disk_mem_usage_filter.h"
#include "i_disk_mem_usage_listener.h"
#include <vespa/log/log.h>
+#include <vespa/searchcore/proton/common/hw_info.h>
LOG_SETUP(".proton.server.disk_mem_usage_filter");
@@ -43,12 +44,12 @@ void
makeDiskStatsMessage(std::ostream &os,
double diskUsed,
double diskLimit,
- const DiskMemUsageFilter::space_info &diskStats)
+ const HwInfo &hwInfo,
+ uint64_t usedDiskSizeBytes)
{
os << "stats: { ";
- os << "capacity: " << diskStats.capacity << ", ";
- os << "free: " << diskStats.free << ", ";
- os << "available: " << diskStats.available << ", ";
+ os << "capacity: " << hwInfo.diskSizeBytes() << ", ";
+ os << "used: " << usedDiskSizeBytes << ", ";
os << "diskUsed: " << diskUsed << ", ";
os << "diskLimit: " << diskLimit << "}";
}
@@ -57,31 +58,31 @@ void
makeDiskLimitMessage(std::ostream &os,
double diskUsed,
double diskLimit,
- const DiskMemUsageFilter::space_info &diskStats)
+ const HwInfo &hwInfo,
+ uint64_t usedDiskSizeBytes)
{
os << "diskLimitReached: { ";
os << "action: \"add more content nodes\", ";
os << "reason: \"disk used (" << diskUsed << ") > disk limit (" << diskLimit << ")\", ";
- makeDiskStatsMessage(os, diskUsed, diskLimit, diskStats);
+ makeDiskStatsMessage(os, diskUsed, diskLimit, hwInfo, usedDiskSizeBytes);
os << "}";
}
-
vespalib::string
makeUnblockingMessage(double memoryUsed,
double memoryLimit,
const vespalib::ProcessMemoryStats &memoryStats,
- uint64_t physicalMemory,
+ const HwInfo &hwInfo,
double diskUsed,
double diskLimit,
- const DiskMemUsageFilter::space_info &diskStats)
+ uint64_t usedDiskSizeBytes)
{
std::ostringstream os;
os << "memoryLimitOK: { ";
- makeMemoryStatsMessage(os, memoryUsed, memoryLimit, memoryStats, physicalMemory);
+ makeMemoryStatsMessage(os, memoryUsed, memoryLimit, memoryStats, hwInfo.memorySizeBytes());
os << "}, ";
os << "diskLimitOK: { ";
- makeDiskStatsMessage(os, diskUsed, diskLimit, diskStats);
+ makeDiskStatsMessage(os, diskUsed, diskLimit, hwInfo, usedDiskSizeBytes);
os << "}";
return os.str();
}
@@ -97,7 +98,7 @@ DiskMemUsageFilter::recalcState(const Guard &guard)
if (memoryUsed > _config._memoryLimit) {
hasMessage = true;
makeMemoryLimitMessage(message, memoryUsed,
- _config._memoryLimit, _memoryStats, _physicalMemory);
+ _config._memoryLimit, _memoryStats, _hwInfo.memorySizeBytes());
}
double diskUsed = getDiskUsedRatio(guard);
if (diskUsed > _config._diskLimit) {
@@ -105,7 +106,7 @@ DiskMemUsageFilter::recalcState(const Guard &guard)
message << ", ";
}
hasMessage = true;
- makeDiskLimitMessage(message, diskUsed, _config._diskLimit, _diskStats);
+ makeDiskLimitMessage(message, diskUsed, _config._diskLimit, _hwInfo, _usedDiskSizeBytes);
}
if (hasMessage) {
if (_acceptWrite) {
@@ -118,10 +119,10 @@ DiskMemUsageFilter::recalcState(const Guard &guard)
vespalib::string unblockMsg = makeUnblockingMessage(memoryUsed,
_config._memoryLimit,
_memoryStats,
- _physicalMemory,
+ _hwInfo,
diskUsed,
_config._diskLimit,
- _diskStats);
+ _usedDiskSizeBytes);
LOG(info, "Write operations are now un-blocked: '%s'", unblockMsg.c_str());
}
_state = State();
@@ -137,23 +138,23 @@ DiskMemUsageFilter::getMemoryUsedRatio(const Guard &guard) const
{
(void) guard;
uint64_t unscaledMemoryUsed = _memoryStats.getAnonymousRss();
- return static_cast<double>(unscaledMemoryUsed) / _physicalMemory;
+ return static_cast<double>(unscaledMemoryUsed) / _hwInfo.memorySizeBytes();
}
double
DiskMemUsageFilter::getDiskUsedRatio(const Guard &guard) const
{
(void) guard;
- double availableDiskSpaceRatio = static_cast<double>(_diskStats.available) /
- static_cast<double>(_diskStats.capacity);
- return 1.0 - availableDiskSpaceRatio;
+ double usedDiskSpaceRatio = static_cast<double>(_usedDiskSizeBytes) /
+ static_cast<double>(_hwInfo.diskSizeBytes());
+ return usedDiskSpaceRatio;
}
-DiskMemUsageFilter::DiskMemUsageFilter(uint64_t physicalMemory_in)
+DiskMemUsageFilter::DiskMemUsageFilter(const HwInfo &hwInfo)
: _lock(),
+ _hwInfo(hwInfo),
_memoryStats(),
- _physicalMemory(physicalMemory_in),
- _diskStats(),
+ _usedDiskSizeBytes(),
_config(),
_state(),
_acceptWrite(true),
@@ -172,10 +173,10 @@ DiskMemUsageFilter::setMemoryStats(vespalib::ProcessMemoryStats memoryStats_in)
}
void
-DiskMemUsageFilter::setDiskStats(space_info diskStats_in)
+DiskMemUsageFilter::setDiskStats(uint64_t usedDiskSizeBytes)
{
Guard guard(_lock);
- _diskStats = diskStats_in;
+ _usedDiskSizeBytes = usedDiskSizeBytes;
recalcState(guard);
}
@@ -194,11 +195,11 @@ DiskMemUsageFilter::getMemoryStats() const
return _memoryStats;
}
-DiskMemUsageFilter::space_info
+uint64_t
DiskMemUsageFilter::getDiskStats() const
{
Guard guard(_lock);
- return _diskStats;
+ return _usedDiskSizeBytes;
}
DiskMemUsageFilter::Config
diff --git a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.h b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.h
index c06d2e2ab0a..1083b969edd 100644
--- a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.h
+++ b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_filter.h
@@ -4,12 +4,12 @@
#include "i_disk_mem_usage_notifier.h"
#include "disk_mem_usage_state.h"
+#include <vespa/searchcore/proton/common/hw_info.h>
#include <vespa/searchcore/proton/persistenceengine/i_resource_write_filter.h>
#include <vespa/vespalib/util/process_memory_stats.h>
-#include <mutex>
#include <atomic>
#include <experimental/filesystem>
-
+#include <mutex>
namespace proton {
@@ -39,10 +39,10 @@ public:
};
private:
- mutable Mutex _lock; // protect _memoryStats, _diskStats, _config, _state
+ mutable Mutex _lock; // protect _memoryStats, _usedDiskSizeBytes, _config, _state
+ HwInfo _hwInfo;
vespalib::ProcessMemoryStats _memoryStats;
- uint64_t _physicalMemory;
- space_info _diskStats;
+ uint64_t _usedDiskSizeBytes;
Config _config;
State _state;
std::atomic<bool> _acceptWrite;
@@ -55,15 +55,15 @@ private:
void notifyDiskMemUsage(const Guard &guard, DiskMemUsageState state);
public:
- DiskMemUsageFilter(uint64_t physicalMememory_in);
+ DiskMemUsageFilter(const HwInfo &hwInfo);
~DiskMemUsageFilter();
void setMemoryStats(vespalib::ProcessMemoryStats memoryStats_in);
- void setDiskStats(space_info diskStats_in);
+ void setDiskStats(uint64_t usedDiskSizeBytes);
void setConfig(Config config);
vespalib::ProcessMemoryStats getMemoryStats() const;
- space_info getDiskStats() const;
+ uint64_t getDiskStats() const;
Config getConfig() const;
- uint64_t getPhysicalMemory() const { return _physicalMemory; }
+ const HwInfo &getHwInfo() const { return _hwInfo; }
double getMemoryUsedRatio() const;
double getDiskUsedRatio() const;
bool acceptWriteOperation() const override;
diff --git a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
index fb7d712db9d..09e44c85298 100644
--- a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.cpp
@@ -3,31 +3,19 @@
#include "disk_mem_usage_sampler.h"
#include <vespa/vespalib/util/timer.h>
#include <vespa/searchlib/common/lambdatask.h>
+#include <experimental/filesystem>
#include <unistd.h>
using search::makeLambdaTask;
namespace proton {
-namespace {
-
-uint64_t getPhysicalMemoryBytes()
-{
- // TODO: Temporal workaround for Docker nodes. Remove when this is part of proton.cfg instead.
- if (const char *memoryEnv = std::getenv("VESPA_TOTAL_MEMORY_MB")) {
- uint64_t physicalMemoryMB = atoll(memoryEnv);
- return physicalMemoryMB * 1024u * 1024u;
- } else {
- return sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
- }
-}
-
-} // namespace proton:<anonymous>
-
-DiskMemUsageSampler::DiskMemUsageSampler(const std::string &path_in,
+DiskMemUsageSampler::DiskMemUsageSampler(const std::string &protonBaseDir,
+ const std::string &vespaHomeDir,
const Config &config)
- : _filter(getPhysicalMemoryBytes()),
- _path(path_in),
+ : _filter(config.hwInfo),
+ _protonBaseDir(protonBaseDir),
+ _vespaHomeDir(vespaHomeDir),
_sampleInterval(60.0),
_periodicTimer()
{
@@ -43,8 +31,8 @@ void
DiskMemUsageSampler::setConfig(const Config &config)
{
_periodicTimer.reset();
- _filter.setConfig(config._filterConfig);
- _sampleInterval = config._sampleInterval;
+ _filter.setConfig(config.filterConfig);
+ _sampleInterval = config.sampleInterval;
sampleUsage();
_periodicTimer = std::make_unique<vespalib::Timer>();
_periodicTimer->scheduleAtFixedRate(makeLambdaTask([this]()
@@ -59,10 +47,35 @@ DiskMemUsageSampler::sampleUsage()
sampleDiskUsage();
}
+namespace {
+
+uint64_t
+sampleDiskUsageInDirectory(const std::experimental::filesystem::path &path)
+{
+ uint64_t result = 0;
+ for (const auto &elem : std::experimental::filesystem::recursive_directory_iterator(path)) {
+ if (!std::experimental::filesystem::is_directory(elem.path())) {
+ result += std::experimental::filesystem::file_size(elem.path());
+ }
+ }
+ return result;
+}
+
+uint64_t
+sampleDiskUsageOnFileSystem(const std::experimental::filesystem::path &path)
+{
+ auto space_info = std::experimental::filesystem::space(path);
+ return (space_info.capacity - space_info.available);
+}
+
+}
+
void
DiskMemUsageSampler::sampleDiskUsage()
{
- _filter.setDiskStats(std::experimental::filesystem::space(_path));
+ bool slowDisk = _filter.getHwInfo().slowDisk();
+ _filter.setDiskStats(slowDisk ? sampleDiskUsageOnFileSystem(_protonBaseDir) :
+ sampleDiskUsageInDirectory(_vespaHomeDir));
}
void
diff --git a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.h b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.h
index 198f111f052..e93a121d0e5 100644
--- a/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.h
+++ b/searchcore/src/vespa/searchcore/proton/server/disk_mem_usage_sampler.h
@@ -13,7 +13,8 @@ namespace proton {
*/
class DiskMemUsageSampler {
DiskMemUsageFilter _filter;
- std::experimental::filesystem::path _path;
+ std::experimental::filesystem::path _protonBaseDir;
+ std::experimental::filesystem::path _vespaHomeDir;
double _sampleInterval;
std::unique_ptr<vespalib::Timer> _periodicTimer;
@@ -22,24 +23,30 @@ class DiskMemUsageSampler {
void sampleMemoryUsage();
public:
struct Config {
- DiskMemUsageFilter::Config _filterConfig;
- double _sampleInterval;
- public:
+ DiskMemUsageFilter::Config filterConfig;
+ double sampleInterval;
+ HwInfo hwInfo;
+
Config()
- : _filterConfig(),
- _sampleInterval(60.0)
+ : filterConfig(),
+ sampleInterval(60.0),
+ hwInfo()
{
}
- Config(double memoryLimit_in, double diskLimit_in,
- double sampleInterval_in)
- : _filterConfig(memoryLimit_in, diskLimit_in),
- _sampleInterval(sampleInterval_in)
+ Config(double memoryLimit_in,
+ double diskLimit_in,
+ double sampleInterval_in,
+ const HwInfo &hwInfo_in)
+ : filterConfig(memoryLimit_in, diskLimit_in),
+ sampleInterval(sampleInterval_in),
+ hwInfo(hwInfo_in)
{
}
};
- DiskMemUsageSampler(const std::string &path_in,
+ DiskMemUsageSampler(const std::string &protonBaseDir,
+ const std::string &vespaHomeDir,
const Config &config);
~DiskMemUsageSampler();
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
index d95b0fd44d1..09a974d3014 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
@@ -32,6 +32,8 @@
#include <vespa/searchlib/expression/forcelink.hpp>
#include <vespa/log/log.h>
+#include <vespa/defaults.h>
+
LOG_SETUP(".proton.server.proton");
using document::DocumentTypeRepo;
@@ -75,12 +77,13 @@ setFS4Compression(const ProtonConfig & proton)
}
DiskMemUsageSampler::Config
-diskMemUsageSamplerConfig(const ProtonConfig &proton)
+diskMemUsageSamplerConfig(const ProtonConfig &proton, const HwInfo &hwInfo)
{
return DiskMemUsageSampler::Config(
proton.writefilter.memorylimit,
proton.writefilter.disklimit,
- proton.writefilter.sampleinterval);
+ proton.writefilter.sampleinterval,
+ hwInfo);
}
}
@@ -223,17 +226,21 @@ Proton::init(const BootstrapConfig::SP & configSnapshot)
{
assert( _initStarted && ! _initComplete );
const ProtonConfig &protonConfig = configSnapshot->getProtonConfig();
- const auto &samplerCfgArgs = protonConfig.hwinfo.disk;
- HwInfoSampler::Config samplerCfg(samplerCfgArgs.writespeed,
- samplerCfgArgs.slowwritespeedlimit,
- samplerCfgArgs.samplewritesize);
+ const auto &hwDiskCfg = protonConfig.hwinfo.disk;
+ const auto &hwMemoryCfg = protonConfig.hwinfo.memory;
+ HwInfoSampler::Config samplerCfg(hwDiskCfg.size,
+ hwDiskCfg.writespeed,
+ hwDiskCfg.slowwritespeedlimit,
+ hwDiskCfg.samplewritesize,
+ hwMemoryCfg.size);
_hwInfoSampler = std::make_unique<HwInfoSampler>(protonConfig.basedir,
samplerCfg);
_hwInfo = _hwInfoSampler->hwInfo();
setFS4Compression(protonConfig);
+ vespalib::string vespaHomeDir = vespa::Defaults::vespaHome();
_diskMemUsageSampler = std::make_unique<DiskMemUsageSampler>
- (protonConfig.basedir,
- diskMemUsageSamplerConfig(protonConfig));
+ (protonConfig.basedir, vespaHomeDir,
+ diskMemUsageSamplerConfig(protonConfig, _hwInfo));
_metricsEngine.reset(new MetricsEngine());
_metricsEngine->addMetricsHook(_metricsHook);
@@ -341,7 +348,7 @@ Proton::applyConfig(const BootstrapConfig::SP & configSnapshot)
protonConfig.search.memory.limiter.minhits);
const DocumentTypeRepo::SP repo = configSnapshot->getDocumentTypeRepoSP();
- _diskMemUsageSampler->setConfig(diskMemUsageSamplerConfig(protonConfig));
+ _diskMemUsageSampler->setConfig(diskMemUsageSamplerConfig(protonConfig, _hwInfo));
if (_memoryFlushConfigUpdater) {
_memoryFlushConfigUpdater->setConfig(protonConfig.flush.memory);
_flushEngine->kick();
diff --git a/searchcore/src/vespa/searchcore/proton/server/resource_usage_explorer.cpp b/searchcore/src/vespa/searchcore/proton/server/resource_usage_explorer.cpp
index afe9f6b85d3..7bd01760141 100644
--- a/searchcore/src/vespa/searchcore/proton/server/resource_usage_explorer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/resource_usage_explorer.cpp
@@ -9,11 +9,10 @@ using namespace vespalib::slime;
namespace proton {
void
-convertDiskStatsToSlime(const DiskMemUsageFilter::space_info &stats, Cursor &object)
+convertDiskStatsToSlime(const HwInfo &hwInfo, uint64_t usedDiskSizeBytes, Cursor &object)
{
- object.setLong("capacity", stats.capacity);
- object.setLong("free", stats.free);
- object.setLong("available", stats.available);
+ object.setLong("capacity", hwInfo.diskSizeBytes());
+ object.setLong("used", usedDiskSizeBytes);
}
void
@@ -39,12 +38,12 @@ ResourceUsageExplorer::get_state(const vespalib::slime::Inserter &inserter, bool
Cursor &disk = object.setObject("disk");
disk.setDouble("usedRatio", _usageFilter.getDiskUsedRatio());
disk.setDouble("usedLimit", config._diskLimit);
- convertDiskStatsToSlime(_usageFilter.getDiskStats(), disk.setObject("stats"));
+ convertDiskStatsToSlime(_usageFilter.getHwInfo(), _usageFilter.getDiskStats(), disk.setObject("stats"));
Cursor &memory = object.setObject("memory");
memory.setDouble("usedRatio", _usageFilter.getMemoryUsedRatio());
memory.setDouble("usedLimit", config._memoryLimit);
- memory.setLong("physicalMemory", _usageFilter.getPhysicalMemory());
+ memory.setLong("physicalMemory", _usageFilter.getHwInfo().memorySizeBytes());
convertMemoryStatsToSlime(_usageFilter.getMemoryStats(), memory.setObject("stats"));
} else {
object.setDouble("disk", _usageFilter.getDiskUsedRatio());