From c96d07682e7529a8617fd948ba0695a1bfbe8dd7 Mon Sep 17 00:00:00 2001 From: yah01 Date: Thu, 23 Nov 2023 15:12:23 +0800 Subject: [PATCH] enhance: enhance the accuracy of memory usage (#28554) before this, Milvus use container/system's memory info to get the memory usage, which could be inaccurate. we allocates the memory by private anon mmap, then `rss - shared` would be the accurate memory usage resolve #28553 --------- Signed-off-by: yah01 --- .golangci.yml | 2 +- internal/core/src/mmap/Column.h | 10 +++--- internal/kv/tikv/txn_tikv.go | 2 +- pkg/util/hardware/hardware_info.go | 29 --------------- pkg/util/hardware/mem_info.go | 49 +++++++++++++++++++++++++ pkg/util/hardware/mem_info_darwin.go | 54 ++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 37 deletions(-) create mode 100644 pkg/util/hardware/mem_info.go create mode 100644 pkg/util/hardware/mem_info_darwin.go diff --git a/.golangci.yml b/.golangci.yml index 2a0c722382..2edeb470d6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -160,4 +160,4 @@ issues: max-same-issues: 0 service: - golangci-lint-version: 1.51.0 # use the fixed version to not introduce new linters unexpectedly + golangci-lint-version: 1.55.2 # use the fixed version to not introduce new linters unexpectedly diff --git a/internal/core/src/mmap/Column.h b/internal/core/src/mmap/Column.h index 7c58e1fe05..2d18d977c9 100644 --- a/internal/core/src/mmap/Column.h +++ b/internal/core/src/mmap/Column.h @@ -33,8 +33,6 @@ namespace milvus { -static int mmap_flags = MAP_SHARED; - class ColumnBase { public: // memory mode ctor @@ -56,7 +54,7 @@ class ColumnBase { data_ = static_cast(mmap(nullptr, cap_size_ + padding_, PROT_READ | PROT_WRITE, - mmap_flags | MAP_ANON, + MAP_PRIVATE | MAP_ANON, -1, 0)); AssertInfo( @@ -77,7 +75,7 @@ class ColumnBase { data_ = static_cast(mmap(nullptr, cap_size_ + padding_, PROT_READ, - mmap_flags, + MAP_SHARED, file.Descriptor(), 0)); AssertInfo(data_ != MAP_FAILED, @@ -100,7 +98,7 @@ class ColumnBase { data_ = static_cast(mmap(nullptr, cap_size_ + padding_, PROT_READ, - mmap_flags, + MAP_SHARED, file.Descriptor(), 0)); AssertInfo(data_ != MAP_FAILED, @@ -191,7 +189,7 @@ class ColumnBase { auto data = static_cast(mmap(nullptr, new_size + padding_, PROT_READ | PROT_WRITE, - mmap_flags | MAP_ANON, + MAP_PRIVATE | MAP_ANON, -1, 0)); diff --git a/internal/kv/tikv/txn_tikv.go b/internal/kv/tikv/txn_tikv.go index 10c25f9e8b..6da371b3ec 100644 --- a/internal/kv/tikv/txn_tikv.go +++ b/internal/kv/tikv/txn_tikv.go @@ -772,7 +772,7 @@ func convertEmptyStringToByte(value string) ([]byte, error) { if len(value) == 0 { return EmptyValueByte, nil } else if value == EmptyValueString { - return nil, fmt.Errorf("Value for key is reserved by EmptyValue: %s", EmptyValueString) + return nil, fmt.Errorf("value for key is reserved by EmptyValue: %s", EmptyValueString) } return []byte(value), nil } diff --git a/pkg/util/hardware/hardware_info.go b/pkg/util/hardware/hardware_info.go index 392ab9af6f..f701be5dd6 100644 --- a/pkg/util/hardware/hardware_info.go +++ b/pkg/util/hardware/hardware_info.go @@ -106,35 +106,6 @@ func GetMemoryCount() uint64 { return stats.Total } -// GetUsedMemoryCount returns the memory usage in bytes. -func GetUsedMemoryCount() uint64 { - icOnce.Do(func() { - ic, icErr = inContainer() - }) - if icErr != nil { - log.Error(icErr.Error()) - return 0 - } - if ic { - // in container, calculate by `cgroups` - used, err := getContainerMemUsed() - if err != nil { - log.Warn("failed to get container memory used", zap.Error(err)) - return 0 - } - return used - } - // not in container, calculate by `gopsutil` - stats, err := mem.VirtualMemory() - if err != nil { - log.Warn("failed to get memory usage count", - zap.Error(err)) - return 0 - } - - return stats.Used -} - // GetFreeMemoryCount returns the free memory in bytes. func GetFreeMemoryCount() uint64 { return GetMemoryCount() - GetUsedMemoryCount() diff --git a/pkg/util/hardware/mem_info.go b/pkg/util/hardware/mem_info.go new file mode 100644 index 0000000000..93e904848b --- /dev/null +++ b/pkg/util/hardware/mem_info.go @@ -0,0 +1,49 @@ +// Copyright (C) 2019-2020 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !darwin && !openbsd && !freebsd +// +build !darwin,!openbsd,!freebsd + +package hardware + +import ( + "os" + + "github.com/shirou/gopsutil/v3/process" + "go.uber.org/zap" + + "github.com/milvus-io/milvus/pkg/log" +) + +var proc *process.Process + +func init() { + var err error + proc, err = process.NewProcess(int32(os.Getpid())) + if err != nil { + panic(err) + } +} + +// GetUsedMemoryCount returns the memory usage in bytes. +func GetUsedMemoryCount() uint64 { + memInfo, err := proc.MemoryInfoEx() + if err != nil { + log.Warn("failed to get memory info", zap.Error(err)) + return 0 + } + + // sub the shared memory to filter out the file-backed map memory usage + return memInfo.RSS - memInfo.Shared +} diff --git a/pkg/util/hardware/mem_info_darwin.go b/pkg/util/hardware/mem_info_darwin.go new file mode 100644 index 0000000000..8be357625e --- /dev/null +++ b/pkg/util/hardware/mem_info_darwin.go @@ -0,0 +1,54 @@ +// Copyright (C) 2019-2020 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build darwin || openbsd || freebsd +// +build darwin openbsd freebsd + +package hardware + +import ( + "github.com/shirou/gopsutil/v3/mem" + "go.uber.org/zap" + + "github.com/milvus-io/milvus/pkg/log" +) + +// GetUsedMemoryCount returns the memory usage in bytes. +func GetUsedMemoryCount() uint64 { + icOnce.Do(func() { + ic, icErr = inContainer() + }) + if icErr != nil { + log.Error(icErr.Error()) + return 0 + } + if ic { + // in container, calculate by `cgroups` + used, err := getContainerMemUsed() + if err != nil { + log.Warn("failed to get container memory used", zap.Error(err)) + return 0 + } + return used + } + // not in container, calculate by `gopsutil` + stats, err := mem.VirtualMemory() + if err != nil { + log.Warn("failed to get memory usage count", + zap.Error(err)) + return 0 + } + + return stats.Used +}