打造先進的記憶體KV資料庫 5 TCP偵聽

2021-07-09 07:44:45 字數 3825 閱讀 3839

作為支援集群的資料庫,必定要與多個客戶端互動資訊,不可能讓資料庫與所有客戶共享位址空間(雖然這樣效能好),所以需要使用tcp協議進行互動資料,(udp協議不可靠。。。棄用),c語言的tcp庫其實還好,但是對於高併發和並行的處理不如go,而且併發鎖機制比較難寫,所以使用go寫了伺服器和客戶端呼叫c的庫,目前版本沒有什麼身份驗證,之後會加上。

package main

// #cgo ldflags: -l ./lib -lmonkeys

// #include "./lib/core.h"

// #include

import "c"

import (

"unsafe"

_"fmt"

"net"

"strings"

)func main()

l,err := net.listentcp("tcp",tcpaddr) //偵聽tcp

if err != nil

forgo handler(conn)

}}func handler(conn net.conn)

buf := make(byte,1024)

length,err := conn.read(buf)

total := uint32(0); //前4個位元組儲存訊息長度

for i := 0;i < 4;i++

"message length:",total)

total -= uint32(length)

for total > 0

if err != nil

translatemessage(conn,&db,buff) //解析訊息

}}func translatemessage(conn net.conn,db **c.database,message byte)

ifparams[0] == "set"

}}else

ifparams[0] == "get"

// }

if(int(r.code) == 0)

}}else

// }

}}else

ifparams[0] == "delete" || params[0] == "remove"

}}else

ifparams[0] == "createdb" else

}else

ifparams[0] == "switchdb" else

}else

ifparams[0] == "dropdb" else

if strings.equalfold("listdb",params[0])

}c.free(unsafe.pointer(r))

}else

total := len(response) + 4

header := make(byte,4)

i := 0

for total > 0

conn.write(response)

}

package main

import

"net"

import

"fmt"

func main()

conn, err := net.dialtcp("tcp", nil, tcpaddr)

if err != nil

for else

if buf1 == "get"else

if buf1 == "remove" || buf1 == "delete" else

if buf1 == "createdb"else

if buf1 == "switchdb"else

if buf1 == "dropdb"else

if buf1 == "listdb"else

if buf1 == "exit"

total := uint32

(0) total = uint32(len(buf) +4)

header := make(byte

,4) i :=0

for total >0

buff := byte{}

buff2 := make(byte

,1024)

length,_ := conn.read(buff2)

total = uint32

(0); //前4個位元組儲存訊息長度

for i :=0;i <4;i++

total -= uint32(length)

for total >0

for i :=0;i <1024;i++

fmt.printf("%c",buff[i])

}fmt.print("\n")

}}

修正:上述**存在嚴重問題:

傳送1k以上資料會無法正確接收

改進**如下:

package tcp

import

"net"

import

"fmt"

func ok(bytes byte) bool

func bytes4uint(bytes byte) uint32

return total

}func uint32bytes(n uint32) byte

return header

}type tcpsession struct //要傳送的資料

received chan

inte***ce{} //接受到的資料

closed bool

//是否已經關閉

}func (s *tcpsession) init() )

s.received = make(chan

inte***ce{})

go s.send()

go s.recv()

}func (s *tcpsession) send()

buf0 := <- s.tosend //取出要傳送的資料

buf := buf0.(byte)

_,err := s.conn.write(buf) //傳送掉

"send,",buf)

if err != nil

}}func (s *tcpsession) recv()

buf := make(byte

,1024)

_,err := s.conn.read(buf)

if err != nil

s.received <- buf

"read,",buf)

}}func (s *tcpsession) sendmessage(bytes byte)

header := uint32bytes(uint32(total)) //計算條數

s.tosend <- header

header)

for i :=0;i < total-1;i++

//傳送最後一段

if total ==0

buf := bytes[0:] //傳送這一段

s.tosend <- buf

}func (s *tcpsession) readmessage() byte else

}for i := uint32

(0);i < total;i++

return buff

}

打造先進的記憶體KV資料庫 1 B樹索引的建立(1)

在搜尋引擎的設計中,往往需要使用倒排索引,在當前記憶體 不斷走低的情況下,記憶體資料庫必然會成為主流。kv資料庫由於適合map reduce用於分布式處理。本系統設計實現如下目標 實現極高效能的查詢 實現分布式集群儲存 實現可靠的日誌系統 索引採用b數索引,這樣做的目的是大大利用cpu的快取,讓每個...

打造支援MySQL 5 X的資料庫建模環境

打造支援mysql 5.x的資料庫建模環境 我有很長時間沒有同大家分享心得了。其實,從2003年底我就已經去濰坊服役,前後大概有一年半左右沒有上過網。我還記得我最後做的是lccwin32開發工具如何使用mysql。今天,我和大家分享一下如何用好 case studio 2.x 這套資料庫建模軟體的經...

打造MySQL版的最新IP資料庫

現在不少人上qq都用顯ip版,不僅能顯示好友的ip位址,還能夠顯示其ip對應的地方,有時可以精確到某城市的某個網咖,甚至可以精確到某棟樓的某房間。這項功能還可以放到論壇或其他網頁上用於顯示來客的位置,也可以放在計數統計系統中用於統計客流 對於php mysql構建的 如果我們能把ip資料庫儲存在my...