mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 16:34:25 +01:00
config tweaks for batching
This commit is contained in:
@@ -132,6 +132,13 @@ listen:
|
|||||||
# Sets the max number of packets to pull from the kernel for each syscall (under systems that support recvmmsg)
|
# Sets the max number of packets to pull from the kernel for each syscall (under systems that support recvmmsg)
|
||||||
# default is 64, does not support reload
|
# default is 64, does not support reload
|
||||||
#batch: 64
|
#batch: 64
|
||||||
|
|
||||||
|
# Control batching between UDP and TUN pipelines
|
||||||
|
#batch:
|
||||||
|
# inbound_size: 32 # packets to queue from UDP before handing to workers
|
||||||
|
# outbound_size: 32 # packets to queue from TUN before handing to workers
|
||||||
|
# flush_interval: 50us # flush partially filled batches after this duration
|
||||||
|
# max_outstanding: 1028 # batches buffered per routine on each channel
|
||||||
# Configure socket buffers for the udp side (outside), leave unset to use the system defaults. Values will be doubled by the kernel
|
# Configure socket buffers for the udp side (outside), leave unset to use the system defaults. Values will be doubled by the kernel
|
||||||
# Default is net.core.rmem_default and net.core.wmem_default (/proc/sys/net/core/rmem_default and /proc/sys/net/core/rmem_default)
|
# Default is net.core.rmem_default and net.core.wmem_default (/proc/sys/net/core/rmem_default and /proc/sys/net/core/rmem_default)
|
||||||
# Maximum is limited by memory in the system, SO_RCVBUFFORCE and SO_SNDBUFFORCE is used to avoid having to raise the system wide
|
# Maximum is limited by memory in the system, SO_RCVBUFFORCE and SO_SNDBUFFORCE is used to avoid having to raise the system wide
|
||||||
|
|||||||
65
interface.go
65
interface.go
@@ -25,10 +25,10 @@ import (
|
|||||||
const (
|
const (
|
||||||
mtu = 9001
|
mtu = 9001
|
||||||
|
|
||||||
inboundBatchSize = 32
|
inboundBatchSizeDefault = 32
|
||||||
outboundBatchSize = 32
|
outboundBatchSizeDefault = 32
|
||||||
batchFlushInterval = 50 * time.Microsecond
|
batchFlushIntervalDefault = 50 * time.Microsecond
|
||||||
maxOutstandingBatches = 1028
|
maxOutstandingBatchesDefault = 1028
|
||||||
)
|
)
|
||||||
|
|
||||||
type InterfaceConfig struct {
|
type InterfaceConfig struct {
|
||||||
@@ -55,9 +55,17 @@ type InterfaceConfig struct {
|
|||||||
reQueryWait time.Duration
|
reQueryWait time.Duration
|
||||||
|
|
||||||
ConntrackCacheTimeout time.Duration
|
ConntrackCacheTimeout time.Duration
|
||||||
|
BatchConfig BatchConfig
|
||||||
l *logrus.Logger
|
l *logrus.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BatchConfig struct {
|
||||||
|
InboundBatchSize int
|
||||||
|
OutboundBatchSize int
|
||||||
|
FlushInterval time.Duration
|
||||||
|
MaxOutstandingPerChan int
|
||||||
|
}
|
||||||
|
|
||||||
type Interface struct {
|
type Interface struct {
|
||||||
hostMap *HostMap
|
hostMap *HostMap
|
||||||
outside udp.Conn
|
outside udp.Conn
|
||||||
@@ -111,15 +119,20 @@ type Interface struct {
|
|||||||
|
|
||||||
packetBatchPool sync.Pool
|
packetBatchPool sync.Pool
|
||||||
outboundBatchPool sync.Pool
|
outboundBatchPool sync.Pool
|
||||||
|
|
||||||
|
inboundBatchSize int
|
||||||
|
outboundBatchSize int
|
||||||
|
batchFlushInterval time.Duration
|
||||||
|
maxOutstandingPerChan int
|
||||||
}
|
}
|
||||||
|
|
||||||
type packetBatch struct {
|
type packetBatch struct {
|
||||||
packets []*packet.Packet
|
packets []*packet.Packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPacketBatch() *packetBatch {
|
func newPacketBatch(capacity int) *packetBatch {
|
||||||
return &packetBatch{
|
return &packetBatch{
|
||||||
packets: make([]*packet.Packet, 0, inboundBatchSize),
|
packets: make([]*packet.Packet, 0, capacity),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +153,7 @@ func (f *Interface) getPacketBatch() *packetBatch {
|
|||||||
b.reset()
|
b.reset()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
return newPacketBatch()
|
return newPacketBatch(f.inboundBatchSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) releasePacketBatch(b *packetBatch) {
|
func (f *Interface) releasePacketBatch(b *packetBatch) {
|
||||||
@@ -152,8 +165,8 @@ type outboundBatch struct {
|
|||||||
payloads []*[]byte
|
payloads []*[]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOutboundBatch() *outboundBatch {
|
func newOutboundBatch(capacity int) *outboundBatch {
|
||||||
return &outboundBatch{payloads: make([]*[]byte, 0, outboundBatchSize)}
|
return &outboundBatch{payloads: make([]*[]byte, 0, capacity)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *outboundBatch) add(buf *[]byte) {
|
func (b *outboundBatch) add(buf *[]byte) {
|
||||||
@@ -173,7 +186,7 @@ func (f *Interface) getOutboundBatch() *outboundBatch {
|
|||||||
b.reset()
|
b.reset()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
return newOutboundBatch()
|
return newOutboundBatch(f.outboundBatchSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) releaseOutboundBatch(b *outboundBatch) {
|
func (f *Interface) releaseOutboundBatch(b *outboundBatch) {
|
||||||
@@ -248,6 +261,20 @@ func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cs := c.pki.getCertState()
|
cs := c.pki.getCertState()
|
||||||
|
|
||||||
|
bc := c.BatchConfig
|
||||||
|
if bc.InboundBatchSize <= 0 {
|
||||||
|
bc.InboundBatchSize = inboundBatchSizeDefault
|
||||||
|
}
|
||||||
|
if bc.OutboundBatchSize <= 0 {
|
||||||
|
bc.OutboundBatchSize = outboundBatchSizeDefault
|
||||||
|
}
|
||||||
|
if bc.FlushInterval <= 0 {
|
||||||
|
bc.FlushInterval = batchFlushIntervalDefault
|
||||||
|
}
|
||||||
|
if bc.MaxOutstandingPerChan <= 0 {
|
||||||
|
bc.MaxOutstandingPerChan = maxOutstandingBatchesDefault
|
||||||
|
}
|
||||||
ifce := &Interface{
|
ifce := &Interface{
|
||||||
pki: c.pki,
|
pki: c.pki,
|
||||||
hostMap: c.HostMap,
|
hostMap: c.HostMap,
|
||||||
@@ -280,16 +307,20 @@ func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
|
|||||||
dropped: metrics.GetOrRegisterCounter("hostinfo.cached_packets.dropped", nil),
|
dropped: metrics.GetOrRegisterCounter("hostinfo.cached_packets.dropped", nil),
|
||||||
},
|
},
|
||||||
|
|
||||||
//TODO: configurable size
|
|
||||||
inbound: make([]chan *packetBatch, c.routines),
|
inbound: make([]chan *packetBatch, c.routines),
|
||||||
outbound: make([]chan *outboundBatch, c.routines),
|
outbound: make([]chan *outboundBatch, c.routines),
|
||||||
|
|
||||||
l: c.l,
|
l: c.l,
|
||||||
|
|
||||||
|
inboundBatchSize: bc.InboundBatchSize,
|
||||||
|
outboundBatchSize: bc.OutboundBatchSize,
|
||||||
|
batchFlushInterval: bc.FlushInterval,
|
||||||
|
maxOutstandingPerChan: bc.MaxOutstandingPerChan,
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < c.routines; i++ {
|
for i := 0; i < c.routines; i++ {
|
||||||
ifce.inbound[i] = make(chan *packetBatch, maxOutstandingBatches)
|
ifce.inbound[i] = make(chan *packetBatch, ifce.maxOutstandingPerChan)
|
||||||
ifce.outbound[i] = make(chan *outboundBatch, maxOutstandingBatches)
|
ifce.outbound[i] = make(chan *outboundBatch, ifce.maxOutstandingPerChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
ifce.inPool = sync.Pool{New: func() any {
|
ifce.inPool = sync.Pool{New: func() any {
|
||||||
@@ -302,11 +333,11 @@ func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
ifce.packetBatchPool = sync.Pool{New: func() any {
|
ifce.packetBatchPool = sync.Pool{New: func() any {
|
||||||
return newPacketBatch()
|
return newPacketBatch(ifce.inboundBatchSize)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ifce.outboundBatchPool = sync.Pool{New: func() any {
|
ifce.outboundBatchPool = sync.Pool{New: func() any {
|
||||||
return newOutboundBatch()
|
return newOutboundBatch(ifce.outboundBatchSize)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
ifce.tryPromoteEvery.Store(c.tryPromoteEvery)
|
ifce.tryPromoteEvery.Store(c.tryPromoteEvery)
|
||||||
@@ -411,7 +442,7 @@ func (f *Interface) listenOut(i int) {
|
|||||||
p.Addr = fromUdpAddr
|
p.Addr = fromUdpAddr
|
||||||
batch.add(p)
|
batch.add(p)
|
||||||
|
|
||||||
if len(batch.packets) >= inboundBatchSize || time.Since(lastFlush) >= batchFlushInterval {
|
if len(batch.packets) >= f.inboundBatchSize || time.Since(lastFlush) >= f.batchFlushInterval {
|
||||||
flush(false)
|
flush(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -465,7 +496,7 @@ func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) {
|
|||||||
*p = (*p)[:n]
|
*p = (*p)[:n]
|
||||||
batch.add(p)
|
batch.add(p)
|
||||||
|
|
||||||
if len(batch.payloads) >= outboundBatchSize || time.Since(lastFlush) >= batchFlushInterval {
|
if len(batch.payloads) >= f.outboundBatchSize || time.Since(lastFlush) >= f.batchFlushInterval {
|
||||||
flush(false)
|
flush(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
main.go
8
main.go
@@ -221,6 +221,13 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batchCfg := BatchConfig{
|
||||||
|
InboundBatchSize: c.GetInt("batch.inbound_size", inboundBatchSizeDefault),
|
||||||
|
OutboundBatchSize: c.GetInt("batch.outbound_size", outboundBatchSizeDefault),
|
||||||
|
FlushInterval: c.GetDuration("batch.flush_interval", batchFlushIntervalDefault),
|
||||||
|
MaxOutstandingPerChan: c.GetInt("batch.max_outstanding", maxOutstandingBatchesDefault),
|
||||||
|
}
|
||||||
|
|
||||||
ifConfig := &InterfaceConfig{
|
ifConfig := &InterfaceConfig{
|
||||||
HostMap: hostMap,
|
HostMap: hostMap,
|
||||||
Inside: tun,
|
Inside: tun,
|
||||||
@@ -242,6 +249,7 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
|||||||
relayManager: NewRelayManager(ctx, l, hostMap, c),
|
relayManager: NewRelayManager(ctx, l, hostMap, c),
|
||||||
punchy: punchy,
|
punchy: punchy,
|
||||||
ConntrackCacheTimeout: conntrackCacheTimeout,
|
ConntrackCacheTimeout: conntrackCacheTimeout,
|
||||||
|
BatchConfig: batchCfg,
|
||||||
l: l,
|
l: l,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user