作為支援集群的資料庫,必定要與多個客戶端互動資訊,不可能讓資料庫與所有客戶共享位址空間(雖然這樣效能好),所以需要使用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...