tlog

package
v1.1.0-alpha-4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2017 License: Apache-2.0 Imports: 16 Imported by: 14

README

GIG TLOG

Transaction Log

TLOG Client

  • TLOG Client library is a client lib that works on zero-os's zerodisk (NBD Server)
  • TLOG Client communicates with TLOG Server via tcp and might be optimized by using dpdk stack.
  • Communication between client and server use binary capnp stream (no RPC).
Data send from the client to server:

Handshake request, send by client upon connection creation

HandshakeRequest
	version  :UInt32;
	vdiskID  :Text;
	firstSequence : UInt64;

Tlog block as tlog entry

Block:
  - sequence : uint64    # block sequence number
  - offset :uint64       # data offset
  - size :uint64         # data size
  - hash :Data           # hash of the data
  - data :Data           # payload data
  - timestamp :uint64    # timestamp of the transaction
  - operation :uint8     # the type of the transaction

See the README there for more details.

TLOG Server

  • TLOG Server store received log entries and store it in memmory

  • After storing log entry it replies to the client on successfull transaction.

  • after timeout or size of the aggregation is reached, we Flush it:

    • aggregate the entries
    • compress the aggregate
    • encrypt the compressed aggregate
    • erasure encode the encrypted aggregate
    • store each pieces of erasure encoded pieces to ardb in parallel way
  • Ideal setup would be to spread erasure coded pieces on different ardb instances.

  • Each instance is used to keep erasure coded part according to its index (erasure coded part index == ardb instance index)

  • We keep only backward links in our blockchain of history. We will add separate forward lining structure later in case it will be needed for the speed of recovery

Flush Settings

settings directly related to flush:

  • flush-size: minimum number of blocks to be flushed
  • flush-time: maximum time we can wait entries before flushing it.
  • k : number of erasure encoded data pieces
  • m : number of erasure encoded coding/parity pieces
  • nonce: hex nonce used for encryption
  • priv-key: encryption private key
Tlog Aggregation structure:

Tlog aggregation per vdisk

name (Text)          # unused now
size (uint64)        # number of blocks in this aggregation
timestamp (uint64)
vdiskID (uint32)     # vdisk ID
Blocks: List(Block)  
prev: Data           # hash of previous aggregation

The server code is in the tlogserver directory, see the README there for more details.

Code Generation

Cap'n Proto code (schema/tlog_schema.capnp.go) can be generated using go generate, make sure to have capnp 0.6.0 installed by running ./install_capnp_0.6.0.sh.

Always make sure to keep the generated code up to date with its relevant schema!

More

More verbose documentation can be found in the /docs directory.

Documentation

Index

Constants

View Source
const (
	KeySize   = 32 // 256-bit key
	NonceSize = 12 // 96-bit nonce
)

static sizes

View Source
const (
	MessageTlogBlock        // tlog block
	MessageForceFlushAtSeq  // force flush at sequence
	MessageWaitNbdSlaveSync // wait for nbd slave to be fully synced

)

Type of message sent from client to server

View Source
const (
	// LastHashPrefix is the last hash ardb key prefix
	LastHashPrefix = "last_hash_"
)

Variables

View Source
var (
	// FirstAggregateHash is used as the prevHash value
	// for the first aggregation
	FirstAggregateHash = zerodisk.NilHash
)
View Source
var (
	// MinSupportedVersion is the minimum supported version
	// that the tlog client and server of this version supports
	MinSupportedVersion = zerodisk.NewVersion(1, 1, 0, zerodisk.VersionStageAlpha)
)

Functions

func ReadCheckMessageType

func ReadCheckMessageType(rd io.Reader) (uint8, error)

ReadCheckMessageType reads type of message from given reader and check the validity of the type

func WriteMessageType

func WriteMessageType(w io.Writer, mType uint8) error

WriteMessageType writes type of message to given writer

Types

type AESDecrypter

type AESDecrypter interface {
	Decrypt(cipher []byte) (plan []byte, err error)
}

AESDecrypter decrypts ciphertext, encrypted by the AESEncrypter, into plaintext.

func NewAESDecrypter

func NewAESDecrypter(privKey, hexNonce string) (decrypter AESDecrypter, err error)

NewAESDecrypter creates a new decrypter, using the given private key and nonce, ready to decrypt your ciphertext (that was encrypted by the AESEncrypter)

type AESEncrypter

type AESEncrypter interface {
	Encrypt(plain []byte) (cipher []byte)
}

AESEncrypter encrypts plaintext into ciphertext, and can be decrypted by using the Decrypter

func NewAESEncrypter

func NewAESEncrypter(privKey, hexNonce string) (encrypter AESEncrypter, err error)

NewAESEncrypter creates a new encrypter, using the given private key and nonce, ready to encrypt your plaintext

type BlockStatus

type BlockStatus int8

BlockStatus is returned by the Tlog server when received block

const (
	BlockStatusFlushFailed              BlockStatus = -2
	BlockStatusRecvFailed               BlockStatus = -1
	BlockStatusRecvOK                   BlockStatus = 1
	BlockStatusFlushOK                  BlockStatus = 2
	BlockStatusForceFlushReceived       BlockStatus = 3
	BlockStatusWaitNbdSlaveSyncReceived BlockStatus = 4
)

Tlog Response status values

func (BlockStatus) Error

func (status BlockStatus) Error() error

Error returns this status as an error, returning nil if the status is not an error

func (BlockStatus) Int8

func (status BlockStatus) Int8() int8

Int8 returns the block status as an int8 value

func (BlockStatus) String

func (status BlockStatus) String() string

String returns the name of the block status

type HandshakeStatus

type HandshakeStatus int8

HandshakeStatus is returned by the Tlog server when receiving the initial handshake message from the client

const (
	// returned when something went wrong internally
	// in the tlogserver during the handshake phase
	HandshakeStatusInternalServerError HandshakeStatus = -4
	// returned when the given VdiskID is not legal
	// could be because it's not valid, or because it already
	// exists on the server
	HandshakeStatusInvalidVdiskID HandshakeStatus = -3
	// returned when the given version by the client
	// was not supported by the server
	HandshakeStatusInvalidVersion HandshakeStatus = -2
	// returned when the given request by the client
	// could not be read
	HandshakeStatusInvalidRequest HandshakeStatus = -1
	// returned when all information was accepted
	HandshakeStatusOK HandshakeStatus = 1
)

Handshake status values

func (HandshakeStatus) Error

func (status HandshakeStatus) Error() error

Error returns this status as an error, returning nil if the status is not an error

func (HandshakeStatus) Int8

func (status HandshakeStatus) Int8() int8

Int8 returns the Handshake status as an int8 value

func (HandshakeStatus) String

func (status HandshakeStatus) String() string

String returns the name of the Hanshake status

type RedisPool

type RedisPool interface {
	// returns amount of DataConnection servers available
	DataConnectionCount() int
	// The application calls the DataConnection with a valid index
	// to get a connection from the pool of data servers.
	// It is important that the caller of this function closes the
	// received connection to return the connection's resources back to the pool.
	DataConnection(index int) redis.Conn
	// Close all open resources.
	Close()
}

RedisPool maintains a collection of premade redis.Pool's,

func AnyRedisPool

func AnyRedisPool(cfg RedisPoolConfig) (RedisPool, error)

AnyRedisPool creates any kind of RedisPool based on the given parameters. + if server configs are given, a RedisPool based on those will be created;

  • if autoFill is true, any missing server configs will be interfered based on the last given server Config (assuming sequential ports);
  • if no server configs are given but the configPath is set, a RedisPool will be created from that config file;
  • if no config path and no server configs are given, and allowInMemory is true, an inmemory redis pool will be created instead;

func InMemoryRedisPool

func InMemoryRedisPool(requiredDataServerCount int) RedisPool

InMemoryRedisPool creates a redis pool using in-memory ardb storage servers.

func NewRedisPool

func NewRedisPool(requiredDataServerCount int, storageServers []config.StorageServerConfig) (RedisPool, error)

NewRedisPool creates a redis pool using the given servers.

func RedisPoolFromConfig

func RedisPoolFromConfig(configPath, vdiskID string, requiredDataServerCount int) (RedisPool, error)

RedisPoolFromConfig creates a redis pool for a vdisk, using the storage cluster defined in the given Blokstor config file, for that vdisk.

type RedisPoolConfig

type RedisPoolConfig struct {
	// RequiredDataServerCount is required by all types of
	// redis pools, in order to validate or create the right amount
	// of storage servers.
	RequiredDataServerCount int

	// When ConfigPath is set, and no ServerConfigs have been specified,
	// the redis pool will be created using the config found on this path.
	ConfigPath string

	// The vdisk ID to use,
	// only required in case the config path is given.
	VdiskID string

	// Create a redis pool straight from these server configs,
	// the redis pool requires RequiredDataServerCount+1 configs to be specified
	ServerConfigs []config.StorageServerConfig
	// AutoFill allows you to automatically complete the server config slice,
	// in case not enough server configs (RequiredDataServerCount+1) have been given.
	// Auto filling is done, by assuming that all missing servers are on
	// the same IP address of the last given server config, using sequential ports,
	// following the port of that last given server config.
	AutoFill bool

	// Enable this boolean, in case you want to allow an in-memory redis pool.
	AllowInMemory bool
}

RedisPoolConfig used to create any kind of supported redis pool, based on the properties set in this config. Note that this config should only be used because the choice is made by input given by the user in one way or another. If the choice is known on compile time, use the correct constructor instead.

type RedisPoolFactory

type RedisPoolFactory interface {
	// NewRedisPool creates a new redis pool for the given vdisk.
	// An error is returned in case that vdisk couldn't be found,
	// or in case that vdisk has not enough (n < k+m) dataservers linked to it,
	// in order to create a valid RedisPool.
	NewRedisPool(vdiskID string) (RedisPool, error)
	// Close any open resources
	Close() error
}

RedisPoolFactory creates a redis pool for a given vdisk.

func AnyRedisPoolFactory

func AnyRedisPoolFactory(cfg RedisPoolFactoryConfig) (RedisPoolFactory, error)

AnyRedisPoolFactory creates any kind of RedisPoolFactory based on the given parameters. + if server configs are given, a static RedisPoolFactory will be created;

  • if autoFill is true, any missing server configs will be interfered based on the last given server Config (assuming sequential ports);
  • if no server configs are given but the configPath is set, a RedisPoolFactory based on that config file will be created;
  • if no config path and no server configs are given, an inmemory redis pool will be created instead;

func ConfigRedisPoolFactory

func ConfigRedisPoolFactory(requiredDataServerCount int, configPath string) (RedisPoolFactory, error)

ConfigRedisPoolFactory creates a RedisPoolFactory using a zerodisk config file. The required amount of data servers is specified upfront, such that at creation of a RedisPool, it is validated that the storage cluster in question has sufficient data servers available.

func InMemoryRedisPoolFactory

func InMemoryRedisPoolFactory(requiredDataServerCount int) RedisPoolFactory

InMemoryRedisPoolFactory creates a static RedisPoolFactory, which returns the same valid inmemory RedisPool for all vdisks, and thus it will always return a valid RedisPool.

func StaticRedisPoolFactory

func StaticRedisPoolFactory(requiredDataServerCount int, storageServers []config.StorageServerConfig) (RedisPoolFactory, error)

StaticRedisPoolFactory creates a RedisPoolFactory, which returns the same valid RedisPool for all vdisks, and thus it will always return a valid RedisPool.

type RedisPoolFactoryConfig

type RedisPoolFactoryConfig struct {
	// RequiredDataServerCount is required by all types of
	// redis pool factories, in order to validate or create the right amount
	// of storage servers.
	RequiredDataServerCount int

	// When ConfigPath is set, and no ServerConfigs have been specified,
	// the redis pool factory will be created using the config found on this path.
	ConfigPath string

	// Create a redis pool factory straight from these server configs,
	// the redis pool factor) requires RequiredDataServerCount+1 configs to be specified
	ServerConfigs []config.StorageServerConfig
	// AutoFill allows you to automatically complete the server config slice,
	// in case not enough server configs (RequiredDataServerCount+1) have been given.
	// Auto filling is done, by assuming that all missing servers are on
	// the same IP address of the last given server config, using sequential ports,
	// following the port of that last given server config.
	AutoFill bool

	// Enable this boolean, in case you want to allow an in-memory redis pool (factory).
	AllowInMemory bool
}

RedisPoolFactoryConfig used to create any kind of supported redis pool factory, based on the properties set in this config. Note that this config should only be used because the choice is made by input given by the user in one way or another. If the choice is known on compile time, use the correct constructor instead.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL