iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Software Development

從零開始打造 Redis:以 Go 建立 Production Ready 應用程式 系列 第 15

[Day 15] 資料持久化(下):從 AOF 恢復資料

  • 分享至 

  • xImage
  •  

從 AOF 恢復資料

server.(Restorer) 介面

定義一個 server.(Restorer) 介面,並且實作 server.(*aofRestorer)

// file: ./internal/server/restorer.go
package server

import (
	"context"
	"errors"
	"io"
	
	"olivine/internal/service"
)

type Restorer interface {
	LoadFromDisk() error
}

func NewRestorer(aof service.AOF, handler Handler) Restorer {
	return &aofRestorer{aof: aof, handler: handler}
}

type aofRestorer struct {
	aof     service.AOF
	handler Handler
}

func (r *aofRestorer) LoadFromDisk() error {
	for {
		cmd, err := r.aof.Read()
		if err != nil {
			if errors.Is(err, io.EOF) {
				return nil
			}
			return err
		}

		if _, err := r.handler.Exec(context.Background(), cmd); err != nil {
			return err
		}
	}
}

使用 server.(Restorer)

在目前的 server.(Server) 介面中新增一個 RestoreFromDisk()

// file: ./internal/server/server.go
type Server interface {
	ListenAndServe() error
	RestoreFromDisk() error
}

並且在 server.(*simpleSrv) 中加入 server.(Restorer) 並實現 RestoreFromDisk()

type simpleSrv struct { 
	handler  Handler 
	restorer Restorer 

	listener net.Listener 
} 
  
func (s *simpleSrv) RestoreFromDisk() error { 
	return s.restorer.LoadFromDisk() 
} 

main.NewApp() 中加入對 server.(Restorer) 的初始化:

// file: ./cmd/olivine/app.go
func NewApp() (*App, error) { 
	aof, err := service.NewAOF(AOFPath) 
	if err != nil { 
		return nil, err 
	} 
  
	handler := server.NewHandler(cmd.NewCommands(repo.NewStorage()), server.NewAOFMiddleware(aof)) 
 
	return &App{ 
		srv: server.NewServer( 
			handler, 
			server.NewRestorer(aof, handler), 
		), 
	}, nil 
}

結語

自此,我自已經完成了一個 Redis 的基本功能:

  • 鍵值存儲
  • TCP 伺服器
  • 資料持久化

而從明天開始,將會進入比較進階的篇章。


上一篇
[Day 14] 資料持久化(中): Middleware
系列文
從零開始打造 Redis:以 Go 建立 Production Ready 應用程式 15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言