mirror of https://github.com/milvus-io/milvus.git
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 <yah2er0ne@outlook.com>pull/28624/head
parent
55800ade84
commit
c96d07682e
|
@ -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
|
||||
|
|
|
@ -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<char*>(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<char*>(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<char*>(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<char*>(mmap(nullptr,
|
||||
new_size + padding_,
|
||||
PROT_READ | PROT_WRITE,
|
||||
mmap_flags | MAP_ANON,
|
||||
MAP_PRIVATE | MAP_ANON,
|
||||
-1,
|
||||
0));
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue