moving UDP payload size to config option, improve throughput performance
moving UDP payload size to optional config choice to imporove throughput performancepull/5201/head
parent
308cab0a52
commit
3bf5d9c969
|
@ -330,6 +330,7 @@ reporting-disabled = false
|
|||
# batch-pending = 5 # number of batches that may be pending in memory
|
||||
# batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit
|
||||
# read-buffer = 0 # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max.
|
||||
# udp-payload-size = 1500 # set the expected UDP payload size, default: 65536
|
||||
|
||||
###
|
||||
### [continuous_queries]
|
||||
|
|
|
@ -31,6 +31,24 @@ const (
|
|||
// Linux: sudo sysctl -w net.core.rmem_max=<read-buffer>
|
||||
// BSD/Darwin: sudo sysctl -w kern.ipc.maxsockbuf=<read-buffer>
|
||||
DefaultReadBuffer = 0
|
||||
|
||||
// DefaultUDPPayloadSize sets the default value of the incoming UDP packet
|
||||
// to the spec max, i.e. 65536. That being said, this value should likely
|
||||
// be tuned lower to match your udp_payload size if using tools like
|
||||
// telegraf.
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure
|
||||
//
|
||||
// Reading packets from a UDP socket in golang actually only pulls
|
||||
// one packet at a time, requiring a very fast reader to keep up with
|
||||
// incoming data at scale. Reducing the overhead of the expected packet
|
||||
// helps allocate memory faster (~10-25µs --> ~150ns with go1.5.2), thereby
|
||||
// speeding up the processing of data coming in.
|
||||
//
|
||||
// NOTE: if you send a payload greater than the UDPPayloadSize, you will
|
||||
// cause a buffer overflow...tune your application very carefully to match
|
||||
// udp_payload for your metrics source
|
||||
DefaultUDPPayloadSize = 65536
|
||||
)
|
||||
|
||||
// Config holds various configuration settings for the UDP listener.
|
||||
|
@ -44,6 +62,7 @@ type Config struct {
|
|||
BatchPending int `toml:"batch-pending"`
|
||||
ReadBuffer int `toml:"read-buffer"`
|
||||
BatchTimeout toml.Duration `toml:"batch-timeout"`
|
||||
UDPPayloadSize int `toml:"udp-payload-size"`
|
||||
}
|
||||
|
||||
// WithDefaults takes the given config and returns a new config with any required
|
||||
|
@ -65,5 +84,8 @@ func (c *Config) WithDefaults() *Config {
|
|||
if d.ReadBuffer == 0 {
|
||||
d.ReadBuffer = DefaultReadBuffer
|
||||
}
|
||||
if d.UDPPayloadSize == 0 {
|
||||
d.UDPPayloadSize = DefaultUDPPayloadSize
|
||||
}
|
||||
return &d
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ retention-policy = "awesomerp"
|
|||
batch-size = 100
|
||||
batch-pending = 9
|
||||
batch-timeout = "10ms"
|
||||
udp-payload-size = 1500
|
||||
`, &c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -38,5 +39,7 @@ batch-timeout = "10ms"
|
|||
t.Fatalf("unexpected batch pending: %d", c.BatchPending)
|
||||
} else if time.Duration(c.BatchTimeout) != (10 * time.Millisecond) {
|
||||
t.Fatalf("unexpected batch timeout: %v", c.BatchTimeout)
|
||||
} else if c.UDPPayloadSize != 1500 {
|
||||
t.Fatalf("unexpected udp-payload-size: %d", c.UDPPayloadSize)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// UDPBufferSize is the maximum UDP packet size
|
||||
// see https://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure
|
||||
UDPBufferSize = 65536
|
||||
|
||||
// Arbitrary, testing indicated that this doesn't typically get over 10
|
||||
parserChanLen = 1000
|
||||
)
|
||||
|
@ -163,7 +159,7 @@ func (s *Service) serve() {
|
|||
return
|
||||
default:
|
||||
// Keep processing.
|
||||
buf := make([]byte, UDPBufferSize)
|
||||
buf := make([]byte, s.config.UDPPayloadSize)
|
||||
n, _, err := s.conn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
s.statMap.Add(statReadFail, 1)
|
||||
|
|
Loading…
Reference in New Issue