Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
milvus
milvus
提交
53ae40b8
M
milvus
项目概览
milvus
/
milvus
11 个月 前同步成功
通知
261
Star
22476
Fork
2472
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
milvus
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
53ae40b8
编写于
2月 01, 2023
作者:
E
Enwei Jiao
提交者:
GitHub
2月 01, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make ratelimiter's config refreshable (#21757)
Signed-off-by:
N
Enwei Jiao
<
enwei.jiao@zilliz.com
>
上级
b12740e1
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
137 addition
and
48 deletion
+137
-48
internal/config/source.go
internal/config/source.go
+24
-6
internal/proxy/multi_rate_limiter.go
internal/proxy/multi_rate_limiter.go
+47
-20
internal/proxy/multi_rate_limiter_test.go
internal/proxy/multi_rate_limiter_test.go
+34
-4
internal/util/paramtable/base_table.go
internal/util/paramtable/base_table.go
+3
-3
internal/util/paramtable/component_param.go
internal/util/paramtable/component_param.go
+4
-0
internal/util/paramtable/quota_param.go
internal/util/paramtable/quota_param.go
+15
-15
internal/util/typeutil/map.go
internal/util/typeutil/map.go
+10
-0
未找到文件。
internal/config/source.go
浏览文件 @
53ae40b8
...
...
@@ -32,12 +32,6 @@ type Source interface {
Close
()
}
// EventHandler handles config change event
type
EventHandler
interface
{
OnEvent
(
event
*
Event
)
GetIdentifier
()
string
}
// EtcdInfo has attribute for config center source initialization
type
EtcdInfo
struct
{
UseEmbed
bool
...
...
@@ -90,3 +84,27 @@ func WithEnvSource(keyFormatter func(string) string) Option {
options
.
EnvKeyFormatter
=
keyFormatter
}
}
// EventHandler handles config change event
type
EventHandler
interface
{
OnEvent
(
event
*
Event
)
GetIdentifier
()
string
}
type
simpleHandler
struct
{
identity
string
onEvent
func
(
*
Event
)
}
func
(
s
*
simpleHandler
)
GetIdentifier
()
string
{
return
s
.
identity
}
// OnEvent implements EventHandler
func
(
s
*
simpleHandler
)
OnEvent
(
event
*
Event
)
{
s
.
onEvent
(
event
)
}
func
NewHandler
(
ident
string
,
onEvent
func
(
*
Event
))
EventHandler
{
return
&
simpleHandler
{
ident
,
onEvent
}
}
internal/proxy/multi_rate_limiter.go
浏览文件 @
53ae40b8
...
...
@@ -18,6 +18,7 @@ package proxy
import
(
"fmt"
"strconv"
"sync"
"time"
...
...
@@ -25,11 +26,13 @@ import (
"github.com/milvus-io/milvus-proto/go-api/commonpb"
"github.com/milvus-io/milvus-proto/go-api/milvuspb"
"github.com/milvus-io/milvus/internal/config"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/metrics"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/util/paramtable"
"github.com/milvus-io/milvus/internal/util/ratelimitutil"
"github.com/milvus-io/milvus/internal/util/typeutil"
)
var
QuotaErrorString
=
map
[
commonpb
.
ErrorCode
]
string
{
...
...
@@ -113,13 +116,13 @@ func (m *MultiRateLimiter) SetQuotaStates(states []milvuspb.QuotaState, codes []
// rateLimiter implements Limiter.
type
rateLimiter
struct
{
limiters
map
[
internalpb
.
RateType
]
*
ratelimitutil
.
Limiter
limiters
*
typeutil
.
ConcurrentMap
[
internalpb
.
RateType
,
*
ratelimitutil
.
Limiter
]
}
// newRateLimiter returns a new RateLimiter.
func
newRateLimiter
()
*
rateLimiter
{
rl
:=
&
rateLimiter
{
limiters
:
make
(
map
[
internalpb
.
RateType
]
*
ratelimitutil
.
Limiter
),
limiters
:
typeutil
.
NewConcurrentMap
[
internalpb
.
RateType
,
*
ratelimitutil
.
Limiter
](
),
}
rl
.
registerLimiters
()
return
rl
...
...
@@ -128,14 +131,18 @@ func newRateLimiter() *rateLimiter {
// limit returns true, the request will be rejected.
// Otherwise, the request will pass.
func
(
rl
*
rateLimiter
)
limit
(
rt
internalpb
.
RateType
,
n
int
)
(
bool
,
float64
)
{
return
!
rl
.
limiters
[
rt
]
.
AllowN
(
time
.
Now
(),
n
),
float64
(
rl
.
limiters
[
rt
]
.
Limit
())
limit
,
ok
:=
rl
.
limiters
.
Get
(
rt
)
if
!
ok
{
return
false
,
-
1
}
return
!
limit
.
AllowN
(
time
.
Now
(),
n
),
float64
(
limit
.
Limit
())
}
// setRates sets new rates for the limiters.
func
(
rl
*
rateLimiter
)
setRates
(
rates
[]
*
internalpb
.
Rate
)
error
{
for
_
,
r
:=
range
rates
{
if
_
,
ok
:=
rl
.
limiters
[
r
.
GetRt
()]
;
ok
{
rl
.
limiters
[
r
.
GetRt
()]
.
SetLimit
(
ratelimitutil
.
Limit
(
r
.
GetR
()))
if
limit
,
ok
:=
rl
.
limiters
.
Get
(
r
.
GetRt
())
;
ok
{
limit
.
SetLimit
(
ratelimitutil
.
Limit
(
r
.
GetR
()))
metrics
.
SetRateGaugeByRateType
(
r
.
GetRt
(),
paramtable
.
GetNodeID
(),
r
.
GetR
())
}
else
{
return
fmt
.
Errorf
(
"unregister rateLimiter for rateType %s"
,
r
.
GetRt
()
.
String
())
...
...
@@ -157,36 +164,56 @@ func (rl *rateLimiter) printRates(rates []*internalpb.Rate) {
// registerLimiters register limiter for all rate types.
func
(
rl
*
rateLimiter
)
registerLimiters
()
{
quotaConfig
:=
&
Params
.
QuotaConfig
for
rt
:=
range
internalpb
.
RateType_name
{
var
r
float64
var
r
*
paramtable
.
ParamItem
switch
internalpb
.
RateType
(
rt
)
{
case
internalpb
.
RateType_DDLCollection
:
r
=
Params
.
QuotaConfig
.
DDLCollectionRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DDLCollectionRate
case
internalpb
.
RateType_DDLPartition
:
r
=
Params
.
QuotaConfig
.
DDLPartitionRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DDLPartitionRate
case
internalpb
.
RateType_DDLIndex
:
r
=
Params
.
QuotaConfig
.
MaxIndexRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
MaxIndexRate
case
internalpb
.
RateType_DDLFlush
:
r
=
Params
.
QuotaConfig
.
MaxFlushRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
MaxFlushRate
case
internalpb
.
RateType_DDLCompaction
:
r
=
Params
.
QuotaConfig
.
MaxCompactionRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
MaxCompactionRate
case
internalpb
.
RateType_DMLInsert
:
r
=
Params
.
QuotaConfig
.
DMLMaxInsertRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DMLMaxInsertRate
case
internalpb
.
RateType_DMLDelete
:
r
=
Params
.
QuotaConfig
.
DMLMaxDeleteRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DMLMaxDeleteRate
case
internalpb
.
RateType_DMLBulkLoad
:
r
=
Params
.
QuotaConfig
.
DMLMaxBulkLoadRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DMLMaxBulkLoadRate
case
internalpb
.
RateType_DQLSearch
:
r
=
Params
.
QuotaConfig
.
DQLMaxSearchRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DQLMaxSearchRate
case
internalpb
.
RateType_DQLQuery
:
r
=
Params
.
QuotaConfig
.
DQLMaxQueryRate
.
GetAsFloat
()
r
=
&
quotaConfig
.
DQLMaxQueryRate
}
limit
:=
ratelimitutil
.
Limit
(
r
)
burst
:=
r
// use rate as burst, because Limiter is with punishment mechanism, burst is insignificant.
rl
.
limiters
[
internalpb
.
RateType
(
rt
)]
=
ratelimitutil
.
NewLimiter
(
limit
,
burst
)
limit
:=
ratelimitutil
.
Limit
(
r
.
GetAsFloat
())
burst
:=
r
.
GetAsFloat
()
// use rate as burst, because Limiter is with punishment mechanism, burst is insignificant.
rl
.
limiters
.
InsertIfNotPresent
(
internalpb
.
RateType
(
rt
),
ratelimitutil
.
NewLimiter
(
limit
,
burst
))
onEvent
:=
func
(
rateType
internalpb
.
RateType
)
func
(
*
config
.
Event
)
{
return
func
(
event
*
config
.
Event
)
{
f
,
err
:=
strconv
.
ParseFloat
(
event
.
Value
,
64
)
if
err
!=
nil
{
log
.
Info
(
"Error format for rateLimit"
,
zap
.
String
(
"rateType"
,
rateType
.
String
()),
zap
.
String
(
"key"
,
event
.
Key
),
zap
.
String
(
"value"
,
event
.
Value
),
zap
.
Error
(
err
))
return
}
limit
,
ok
:=
rl
.
limiters
.
Get
(
rateType
)
if
!
ok
{
return
}
limit
.
SetLimit
(
ratelimitutil
.
Limit
(
f
))
}
}(
internalpb
.
RateType
(
rt
))
paramtable
.
Get
()
.
Watch
(
r
.
Key
,
config
.
NewHandler
(
fmt
.
Sprintf
(
"rateLimiter-%d"
,
rt
),
onEvent
))
log
.
Info
(
"RateLimiter register for rateType"
,
zap
.
String
(
"rateType"
,
internalpb
.
RateType_name
[
rt
]),
zap
.
String
(
"rate"
,
ratelimitutil
.
Limit
(
r
)
.
String
()),
zap
.
String
(
"rate"
,
ratelimitutil
.
Limit
(
r
.
GetAsFloat
()
)
.
String
()),
zap
.
String
(
"burst"
,
fmt
.
Sprintf
(
"%v"
,
burst
)))
}
}
internal/proxy/multi_rate_limiter_test.go
浏览文件 @
53ae40b8
...
...
@@ -17,12 +17,16 @@
package
proxy
import
(
"context"
"fmt"
"math"
"math/rand"
"testing"
"time"
"github.com/milvus-io/milvus-proto/go-api/commonpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/util/etcd"
"github.com/milvus-io/milvus/internal/util/paramtable"
"github.com/milvus-io/milvus/internal/util/ratelimitutil"
"github.com/stretchr/testify/assert"
...
...
@@ -34,7 +38,7 @@ func TestMultiRateLimiter(t *testing.T) {
paramtable
.
Get
()
.
Save
(
Params
.
QuotaConfig
.
QuotaAndLimitsEnabled
.
Key
,
"true"
)
multiLimiter
:=
NewMultiRateLimiter
()
for
_
,
rt
:=
range
internalpb
.
RateType_value
{
multiLimiter
.
globalRateLimiter
.
limiters
[
internalpb
.
RateType
(
rt
)]
=
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
multiLimiter
.
globalRateLimiter
.
limiters
.
Insert
(
internalpb
.
RateType
(
rt
),
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
)
}
for
_
,
rt
:=
range
internalpb
.
RateType_value
{
errCode
:=
multiLimiter
.
Check
(
internalpb
.
RateType
(
rt
),
1
)
...
...
@@ -81,9 +85,8 @@ func TestMultiRateLimiter(t *testing.T) {
func
TestRateLimiter
(
t
*
testing
.
T
)
{
t
.
Run
(
"test limit"
,
func
(
t
*
testing
.
T
)
{
limiter
:=
newRateLimiter
()
limiter
.
registerLimiters
()
for
_
,
rt
:=
range
internalpb
.
RateType_value
{
limiter
.
limiters
[
internalpb
.
RateType
(
rt
)]
=
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
limiter
.
limiters
.
Insert
(
internalpb
.
RateType
(
rt
),
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
)
}
for
_
,
rt
:=
range
internalpb
.
RateType_value
{
ok
,
_
:=
limiter
.
limit
(
internalpb
.
RateType
(
rt
),
1
)
...
...
@@ -98,7 +101,7 @@ func TestRateLimiter(t *testing.T) {
t
.
Run
(
"test setRates"
,
func
(
t
*
testing
.
T
)
{
limiter
:=
newRateLimiter
()
for
_
,
rt
:=
range
internalpb
.
RateType_value
{
limiter
.
limiters
[
internalpb
.
RateType
(
rt
)]
=
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
limiter
.
limiters
.
Insert
(
internalpb
.
RateType
(
rt
),
ratelimitutil
.
NewLimiter
(
ratelimitutil
.
Limit
(
1000
),
1
)
)
}
zeroRates
:=
make
([]
*
internalpb
.
Rate
,
0
,
len
(
internalpb
.
RateType_value
))
...
...
@@ -116,4 +119,31 @@ func TestRateLimiter(t *testing.T) {
}
}
})
t
.
Run
(
"tests refresh rate by config"
,
func
(
t
*
testing
.
T
)
{
limiter
:=
newRateLimiter
()
etcdCli
,
_
:=
etcd
.
GetEtcdClient
(
Params
.
EtcdCfg
.
UseEmbedEtcd
.
GetAsBool
(),
Params
.
EtcdCfg
.
EtcdUseSSL
.
GetAsBool
(),
Params
.
EtcdCfg
.
Endpoints
.
GetAsStrings
(),
Params
.
EtcdCfg
.
EtcdTLSCert
.
GetValue
(),
Params
.
EtcdCfg
.
EtcdTLSKey
.
GetValue
(),
Params
.
EtcdCfg
.
EtcdTLSCACert
.
GetValue
(),
Params
.
EtcdCfg
.
EtcdTLSMinVersion
.
GetValue
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
time
.
Second
)
defer
cancel
()
newRate
:=
fmt
.
Sprintf
(
"%.4f"
,
rand
.
Float64
())
etcdCli
.
KV
.
Put
(
ctx
,
"by-dev/config/quotaAndLimits/ddl/collectionRate"
,
newRate
)
etcdCli
.
KV
.
Put
(
ctx
,
"by-dev/config/quotaAndLimits/ddl/partitionRate"
,
"invalid"
)
assert
.
Eventually
(
t
,
func
()
bool
{
limit
,
_
:=
limiter
.
limiters
.
Get
(
internalpb
.
RateType_DDLCollection
)
return
newRate
==
limit
.
Limit
()
.
String
()
},
20
*
time
.
Second
,
time
.
Second
)
limit
,
_
:=
limiter
.
limiters
.
Get
(
internalpb
.
RateType_DDLPartition
)
assert
.
Equal
(
t
,
"+inf"
,
limit
.
Limit
()
.
String
())
})
}
internal/util/paramtable/base_table.go
浏览文件 @
53ae40b8
...
...
@@ -97,7 +97,7 @@ func (gp *BaseTable) init(refreshInterval int) {
}
gp
.
initConfigsFromLocal
(
refreshInterval
)
gp
.
initConfigsFromRemote
(
refreshInterval
)
gp
.
InitLogCf
g
()
gp
.
initLo
g
()
}
func
(
gp
*
BaseTable
)
initConfigsFromLocal
(
refreshInterval
int
)
{
...
...
@@ -203,8 +203,8 @@ func (gp *BaseTable) Reset(key string) error {
return
nil
}
//
InitLogCf
g init log of the base table
func
(
gp
*
BaseTable
)
InitLogCf
g
()
{
//
initLo
g init log of the base table
func
(
gp
*
BaseTable
)
initLo
g
()
{
gp
.
Log
=
log
.
Config
{}
format
:=
gp
.
GetWithDefault
(
"log.format"
,
DefaultLogFormat
)
gp
.
Log
.
Format
=
format
...
...
internal/util/paramtable/component_param.go
浏览文件 @
53ae40b8
...
...
@@ -143,6 +143,10 @@ func (p *ComponentParam) GetAll() map[string]string {
return
p
.
mgr
.
GetConfigs
()
}
func
(
p
*
ComponentParam
)
Watch
(
key
string
,
watcher
config
.
EventHandler
)
{
p
.
mgr
.
Dispatcher
.
Register
(
key
,
watcher
)
}
// /////////////////////////////////////////////////////////////////////////////
// --- common ---
type
commonConfig
struct
{
...
...
internal/util/paramtable/quota_param.go
浏览文件 @
53ae40b8
...
...
@@ -48,33 +48,33 @@ type quotaConfig struct {
// ddl
DDLLimitEnabled
ParamItem
`refreshable:"true"`
DDLCollectionRate
ParamItem
`refreshable:"
fals
e"`
DDLPartitionRate
ParamItem
`refreshable:"
fals
e"`
DDLCollectionRate
ParamItem
`refreshable:"
tru
e"`
DDLPartitionRate
ParamItem
`refreshable:"
tru
e"`
IndexLimitEnabled
ParamItem
`refreshable:"true"`
MaxIndexRate
ParamItem
`refreshable:"
fals
e"`
MaxIndexRate
ParamItem
`refreshable:"
tru
e"`
FlushLimitEnabled
ParamItem
`refreshable:"true"`
MaxFlushRate
ParamItem
`refreshable:"
fals
e"`
MaxFlushRate
ParamItem
`refreshable:"
tru
e"`
CompactionLimitEnabled
ParamItem
`refreshable:"true"`
MaxCompactionRate
ParamItem
`refreshable:"
fals
e"`
MaxCompactionRate
ParamItem
`refreshable:"
tru
e"`
// dml
DMLLimitEnabled
ParamItem
`refreshable:"true"`
DMLMaxInsertRate
ParamItem
`refreshable:"
fals
e"`
DMLMinInsertRate
ParamItem
`refreshable:"
fals
e"`
DMLMaxDeleteRate
ParamItem
`refreshable:"
fals
e"`
DMLMinDeleteRate
ParamItem
`refreshable:"
fals
e"`
DMLMaxBulkLoadRate
ParamItem
`refreshable:"
fals
e"`
DMLMinBulkLoadRate
ParamItem
`refreshable:"
fals
e"`
DMLMaxInsertRate
ParamItem
`refreshable:"
tru
e"`
DMLMinInsertRate
ParamItem
`refreshable:"
tru
e"`
DMLMaxDeleteRate
ParamItem
`refreshable:"
tru
e"`
DMLMinDeleteRate
ParamItem
`refreshable:"
tru
e"`
DMLMaxBulkLoadRate
ParamItem
`refreshable:"
tru
e"`
DMLMinBulkLoadRate
ParamItem
`refreshable:"
tru
e"`
// dql
DQLLimitEnabled
ParamItem
`refreshable:"true"`
DQLMaxSearchRate
ParamItem
`refreshable:"
fals
e"`
DQLMinSearchRate
ParamItem
`refreshable:"
fals
e"`
DQLMaxQueryRate
ParamItem
`refreshable:"
fals
e"`
DQLMinQueryRate
ParamItem
`refreshable:"
fals
e"`
DQLMaxSearchRate
ParamItem
`refreshable:"
tru
e"`
DQLMinSearchRate
ParamItem
`refreshable:"
tru
e"`
DQLMaxQueryRate
ParamItem
`refreshable:"
tru
e"`
DQLMinQueryRate
ParamItem
`refreshable:"
tru
e"`
// limits
MaxCollectionNum
ParamItem
`refreshable:"true"`
...
...
internal/util/typeutil/map.go
浏览文件 @
53ae40b8
...
...
@@ -58,6 +58,16 @@ func (m *ConcurrentMap[K, V]) InsertIfNotPresent(key K, value V) {
}
}
// Insert inserts the key-value pair to the concurrent map
func
(
m
*
ConcurrentMap
[
K
,
V
])
Insert
(
key
K
,
value
V
)
{
_
,
loaded
:=
m
.
inner
.
LoadOrStore
(
key
,
value
)
if
!
loaded
{
m
.
len
.
Inc
()
}
else
{
m
.
inner
.
Store
(
key
,
value
)
}
}
func
(
m
*
ConcurrentMap
[
K
,
V
])
Get
(
key
K
)
(
V
,
bool
)
{
var
zeroValue
V
value
,
ok
:=
m
.
inner
.
Load
(
key
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录