Implement batched database operations for improved performance
- Add BatchedDatabaseHandler that batches prefix, ASN, and peering operations - Add BatchedPeerHandler that batches peer update operations - Batch operations are deduped and flushed every 100-200ms or when batch size is reached - Add EnableBatchedDatabaseWrites config option (enabled by default) - Properly flush remaining batches on shutdown - This significantly reduces database write pressure and improves throughput
This commit is contained in:
@@ -41,15 +41,18 @@ type Dependencies struct {
|
||||
|
||||
// RouteWatch represents the main application instance
|
||||
type RouteWatch struct {
|
||||
db database.Store
|
||||
routingTable *routingtable.RoutingTable
|
||||
streamer *streamer.Streamer
|
||||
server *server.Server
|
||||
snapshotter *snapshotter.Snapshotter
|
||||
logger *slog.Logger
|
||||
maxRuntime time.Duration
|
||||
shutdown bool
|
||||
mu sync.Mutex
|
||||
db database.Store
|
||||
routingTable *routingtable.RoutingTable
|
||||
streamer *streamer.Streamer
|
||||
server *server.Server
|
||||
snapshotter *snapshotter.Snapshotter
|
||||
logger *slog.Logger
|
||||
maxRuntime time.Duration
|
||||
shutdown bool
|
||||
mu sync.Mutex
|
||||
config *config.Config
|
||||
batchedDBHandler *BatchedDatabaseHandler
|
||||
batchedPeerHandler *BatchedPeerHandler
|
||||
}
|
||||
|
||||
// isTruthy returns true if the value is considered truthy
|
||||
@@ -72,6 +75,7 @@ func New(deps Dependencies) *RouteWatch {
|
||||
server: deps.Server,
|
||||
logger: deps.Logger,
|
||||
maxRuntime: deps.Config.MaxRuntime,
|
||||
config: deps.Config,
|
||||
}
|
||||
|
||||
// Create snapshotter if enabled
|
||||
@@ -101,17 +105,25 @@ func (rw *RouteWatch) Run(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Register database handler to process BGP UPDATE messages
|
||||
dbHandler := NewDatabaseHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(dbHandler)
|
||||
if rw.config.EnableBatchedDatabaseWrites {
|
||||
rw.logger.Info("Using batched database handlers for improved performance")
|
||||
rw.batchedDBHandler = NewBatchedDatabaseHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(rw.batchedDBHandler)
|
||||
|
||||
rw.batchedPeerHandler = NewBatchedPeerHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(rw.batchedPeerHandler)
|
||||
} else {
|
||||
dbHandler := NewDatabaseHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(dbHandler)
|
||||
|
||||
peerHandler := NewPeerHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(peerHandler)
|
||||
}
|
||||
|
||||
// Register routing table handler to maintain in-memory routing table
|
||||
rtHandler := NewRoutingTableHandler(rw.routingTable, rw.logger)
|
||||
rw.streamer.RegisterHandler(rtHandler)
|
||||
|
||||
// Register peer tracking handler to track all peers
|
||||
peerHandler := NewPeerHandler(rw.db, rw.logger)
|
||||
rw.streamer.RegisterHandler(peerHandler)
|
||||
|
||||
// Start periodic routing table stats logging
|
||||
go rw.logRoutingTableStats(ctx)
|
||||
|
||||
@@ -147,6 +159,16 @@ func (rw *RouteWatch) Shutdown() {
|
||||
rw.shutdown = true
|
||||
rw.mu.Unlock()
|
||||
|
||||
// Stop batched handlers first to flush remaining batches
|
||||
if rw.batchedDBHandler != nil {
|
||||
rw.logger.Info("Flushing batched database handler")
|
||||
rw.batchedDBHandler.Stop()
|
||||
}
|
||||
if rw.batchedPeerHandler != nil {
|
||||
rw.logger.Info("Flushing batched peer handler")
|
||||
rw.batchedPeerHandler.Stop()
|
||||
}
|
||||
|
||||
// Stop services
|
||||
rw.streamer.Stop()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user