use cache reduce malloc

This commit is contained in:
hebo
2019-09-09 21:36:18 +08:00
parent 3294a0fc5f
commit 4086028217
12 changed files with 280 additions and 169 deletions

View File

@@ -4,4 +4,5 @@ import "github.com/zr-hebo/sniffer-agent/model"
type ConnSession interface {
ReceiveTCPPacket(*model.TCPPacket)
Close()
}

View File

@@ -3,6 +3,7 @@ package mysql
import (
"flag"
"fmt"
"github.com/zr-hebo/sniffer-agent/model"
"regexp"
)
@@ -17,6 +18,7 @@ var (
adminPasswd string
coverRangePool = NewCoveragePool()
localStmtCache = model.NewSliceBufferPool("statement cache", MaxMysqlPacketLen)
)
func init() {

View File

@@ -0,0 +1,133 @@
package mysql
import (
log "github.com/sirupsen/logrus"
)
// coverageNode record tcp package begin and end seq id
type coverageNode struct {
begin int64
end int64
next *coverageNode
crp *coveragePool
}
func newCoverage(begin, end int64) (*coverageNode) {
return &coverageNode{
begin: begin,
end: end,
}
}
func (crn *coverageNode) Recovery() {
crn.crp.Enqueue(crn)
}
type coverRanges struct {
head *coverageNode
}
func NewCoverRanges() *coverRanges {
return &coverRanges{
head: &coverageNode{
begin: -1,
},
}
}
func (crs *coverRanges) clear() {
currRange := crs.head.next;
for currRange != nil {
node := currRange
currRange = currRange.next
node.Recovery()
}
crs.head.next = nil
}
func (crs *coverRanges) addRange(node *coverageNode) {
// insert range in asc order
var currRange = crs.head;
for currRange != nil && currRange.next != nil {
checkRange := currRange.next
if checkRange != nil && checkRange.begin >= node.begin {
currRange.next = node
node.next = checkRange
node = nil
break
} else {
currRange = checkRange
}
}
if node != nil && currRange != nil {
currRange.next = node
}
crs.mergeRanges()
}
func (crs *coverRanges) mergeRanges() {
// merge ranges
currRange := crs.head.next
for currRange != nil && currRange.next != nil {
checkRange := currRange.next
if currRange.end >= checkRange.begin && currRange.end < checkRange.end {
currRange.end = checkRange.end
currRange.next = checkRange.next
checkRange.Recovery()
} else {
currRange = currRange.next
}
}
}
type coveragePool struct {
queue chan *coverageNode
}
func NewCoveragePool() (cp *coveragePool) {
return &coveragePool{
queue: make(chan *coverageNode, 256),
}
}
func (crp *coveragePool) NewCoverage(begin, end int64)(cn *coverageNode) {
cn = crp.Dequeue()
cn.begin = begin
cn.end = end
return
}
func (crp *coveragePool) Enqueue(cn *coverageNode) {
log.Debugf("coveragePool enqueue: %d", len(crp.queue))
if cn == nil {
return
}
crp.queue <- cn
}
func (crp *coveragePool) Dequeue() (cn *coverageNode) {
log.Debugf("coveragePool dequeue: %d", len(crp.queue))
defer func() {
cn.begin = -1
cn.end = -1
cn.next = nil
cn.crp = crp
}()
select {
case cn = <- crp.queue:
return
default:
cn = &coverageNode{}
return
}
}

View File

@@ -7,128 +7,3 @@ type handshakeResponse41 struct {
DBName string
Auth []byte
}
// coverageNode record tcp package begin and end seq id
type coverageNode struct {
begin int64
end int64
next *coverageNode
crp *coveragePool
}
func newCoverage(begin, end int64) (*coverageNode) {
return &coverageNode{
begin: begin,
end: end,
}
}
func (crn *coverageNode) Recovery() {
crn.crp.Enqueue(crn)
}
type coveragePool struct {
queue []*coverageNode
}
func NewCoveragePool() (cp *coveragePool) {
return &coveragePool{
queue: make([]*coverageNode, 0, 256),
}
}
func (crp *coveragePool) Enqueue(cn *coverageNode) {
if cn == nil {
return
}
crp.queue = append(crp.queue, cn)
}
func (crp *coveragePool) NewCoverage(begin, end int64)(cn *coverageNode) {
cn = crp.Dequeue()
cn.begin = begin
cn.end = end
return
}
func (crp *coveragePool) Dequeue() (cn *coverageNode) {
defer func() {
cn.begin = -1
cn.end = -1
cn.next = nil
cn.crp = crp
}()
if len(crp.queue) < 1 {
cn = &coverageNode{}
return
}
cn = crp.queue[0]
crp.queue = crp.queue[1:]
return
}
type coverRanges struct {
head *coverageNode
}
func NewCoverRanges() *coverRanges {
return &coverRanges{
head: &coverageNode{
begin: -1,
},
}
}
func (crs *coverRanges) clear() {
currRange := crs.head.next;
if currRange != nil {
node := currRange
currRange = currRange.next
node.Recovery()
}
crs.head.next = nil
}
func (crs *coverRanges) addRange(node *coverageNode) {
// insert range in asc order
var currRange = crs.head;
for currRange != nil && currRange.next != nil {
checkRange := currRange.next
if checkRange != nil && checkRange.begin >= node.begin {
currRange.next = node
node.next = checkRange
node = nil
break
} else {
currRange = checkRange
}
}
if node != nil {
currRange.next = node
}
crs.mergeRanges()
}
func (crs *coverRanges) mergeRanges() {
// merge ranges
currRange := crs.head.next
for currRange != nil && currRange.next != nil {
checkRange := currRange.next
if currRange.end >= checkRange.begin && currRange.end < checkRange.end {
currRange.end = checkRange.end
currRange.next = checkRange.next
checkRange.Recovery()
} else {
currRange = currRange.next
}
}
}

View File

@@ -122,7 +122,12 @@ func (ms *MysqlSession) checkFinish() bool {
return false
}
func (ms *MysqlSession) Close() {
ms.clear()
}
func (ms *MysqlSession) clear() {
localStmtCache.Enqueue(ms.cachedStmtBytes)
ms.cachedStmtBytes = nil
ms.expectReceiveSize = -1
ms.expectSendSize = -1
@@ -155,15 +160,13 @@ func (ms *MysqlSession) readFromClient(seqID int64, bytes []byte) {
ms.beginSeqID = seqID
ms.endSeqID = seqID
// if len(ms.cachedStmtBytes) > 0 {
// copy(newCache[:len(ms.cachedStmtBytes)], ms.cachedStmtBytes)
// }
if int64(ms.expectReceiveSize) < int64(len(contents)) {
log.Warnf("receive invalid mysql packet")
return
}
newCache := make([]byte, ms.expectReceiveSize)
newCache := localStmtCache.DequeueWithInit(ms.expectReceiveSize)
copy(newCache[:len(contents)], contents)
ms.cachedStmtBytes = newCache
@@ -310,5 +313,5 @@ func filterQueryPieceBySQL(mqp *model.PooledMysqlQueryPiece, querySQL []byte) (m
func (ms *MysqlSession) composeQueryPiece() (mqp *model.PooledMysqlQueryPiece) {
return model.NewPooledMysqlQueryPiece(
ms.connectionID, ms.clientHost, ms.visitUser, ms.visitDB, ms.clientHost, ms.serverIP,
ms.clientPort, ms.serverPort, communicator.GetThrowPacketRate(), ms.stmtBeginTime)
ms.clientPort, ms.serverPort, communicator.GetMysqlThrowPacketRate(), ms.stmtBeginTime)
}