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

66
model/cache_pool.go Normal file
View File

@@ -0,0 +1,66 @@
package model
import (
"fmt"
"reflect"
"unsafe"
log "github.com/sirupsen/logrus"
)
type sliceBufferPool struct {
queue chan []byte
bufferSize int
name string
}
func NewSliceBufferPool(name string, bufferSize int) (sbp *sliceBufferPool) {
return &sliceBufferPool{
queue: make(chan []byte, 512),
bufferSize: bufferSize,
name: name,
}
}
func (sbp *sliceBufferPool) Enqueue(buffer []byte) {
defer func() {
log.Debugf("after enqueue from %s, there is %d elements", sbp.name, len(sbp.queue))
}()
if cap(buffer) < 1 {
return
}
sbp.queue <- buffer
}
func (sbp *sliceBufferPool) DequeueWithInit(initSize int) (buffer []byte) {
if initSize >= sbp.bufferSize {
panic(fmt.Sprintf("package size bigger than max buffer size need deal:%d",
sbp.bufferSize))
}
defer func() {
// reset cache byte
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&buffer))
pbytes.Len = initSize
}()
buffer = sbp.Dequeue()
return
}
func (sbp *sliceBufferPool) Dequeue() (buffer []byte) {
defer func() {
log.Debugf("after dequeue from %s, there is %d elements", sbp.name, len(sbp.queue))
}()
select {
case buffer = <- sbp.queue:
return
default:
buffer = make([]byte, 0, sbp.bufferSize)
return
}
}

View File

@@ -1,14 +1,16 @@
package model
import (
// "encoding/json"
"github.com/json-iterator/go"
"bytes"
"encoding/json"
// "github.com/json-iterator/go"
"time"
"github.com/pingcap/tidb/util/hack"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
// var json = jsoniter.ConfigCompatibleWithStandardLibrary
type QueryPiece interface {
String() *string
@@ -32,20 +34,23 @@ type MysqlQueryPiece struct {
ThrowPacketRate float64 `json:"tpr"`
BeginTime int64 `json:"bt"`
CostTimeInMS int64 `json:"cms"`
jsonContent []byte `json:"-"`
}
type PooledMysqlQueryPiece struct {
MysqlQueryPiece
recoverPool *mysqlQueryPiecePool
sliceBufferPool *sliceBufferPool
}
const (
datetimeFormat = "2006-01-02 15:04:05"
millSecondUnit = int64(time.Millisecond)
)
var (
mqpp = NewMysqlQueryPiecePool()
localSliceBufferPool = NewSliceBufferPool("json cache", 2*1024*1024)
)
func NewPooledMysqlQueryPiece(
@@ -53,11 +58,6 @@ func NewPooledMysqlQueryPiece(
clientPort, serverPort int, throwPacketRate float64, stmtBeginTime int64) (
mqp *PooledMysqlQueryPiece) {
mqp = mqpp.Dequeue()
if mqp == nil {
mqp = &PooledMysqlQueryPiece{
MysqlQueryPiece: MysqlQueryPiece{},
}
}
nowInMS := time.Now().UnixNano() / millSecondUnit
mqp.SessionID = sessionID
@@ -73,6 +73,7 @@ func NewPooledMysqlQueryPiece(
mqp.BeginTime = stmtBeginTime
mqp.CostTimeInMS = nowInMS - stmtBeginTime
mqp.recoverPool = mqpp
mqp.sliceBufferPool = localSliceBufferPool
return
}
@@ -83,13 +84,23 @@ func (mqp *MysqlQueryPiece) String() (*string) {
return &contentStr
}
func (mqp *MysqlQueryPiece) Bytes() (bytes []byte) {
content, err := json.Marshal(mqp)
if err != nil {
return []byte(err.Error())
func (mqp *MysqlQueryPiece) Bytes() (content []byte) {
// content, err := json.Marshal(mqp)
if len(mqp.jsonContent) > 0 {
return mqp.jsonContent
}
return content
var cacheBuffer = localSliceBufferPool.Dequeue()
buffer := bytes.NewBuffer(cacheBuffer)
err := json.NewEncoder(buffer).Encode(mqp)
if err != nil {
mqp.jsonContent = []byte(err.Error())
} else {
mqp.jsonContent = buffer.Bytes()
}
return mqp.jsonContent
}
func (mqp *MysqlQueryPiece) GetSQL() (str *string) {
@@ -106,4 +117,6 @@ func (mqp *MysqlQueryPiece) SetNeedSyncSend(syncSend bool) {
func (pmqp *PooledMysqlQueryPiece) Recovery() {
pmqp.recoverPool.Enqueue(pmqp)
pmqp.sliceBufferPool.Enqueue(pmqp.jsonContent[:0])
pmqp.jsonContent = nil
}

View File

@@ -5,13 +5,13 @@ import (
)
type mysqlQueryPiecePool struct {
queue []*PooledMysqlQueryPiece
queue chan *PooledMysqlQueryPiece
lock sync.Mutex
}
func NewMysqlQueryPiecePool() (mqpp *mysqlQueryPiecePool) {
return &mysqlQueryPiecePool{
queue: make([]*PooledMysqlQueryPiece, 0, 5000),
queue: make(chan *PooledMysqlQueryPiece, 1024),
}
}
@@ -19,18 +19,21 @@ func (mqpp *mysqlQueryPiecePool) Enqueue(pmqp *PooledMysqlQueryPiece) {
mqpp.lock.Lock()
defer mqpp.lock.Unlock()
mqpp.queue = append(mqpp.queue, pmqp)
mqpp.queue <- pmqp
}
func (mqpp *mysqlQueryPiecePool) Dequeue() (pmqp *PooledMysqlQueryPiece) {
mqpp.lock.Lock()
defer mqpp.lock.Unlock()
if len(mqpp.queue) < 1 {
return nil
select {
case pmqp = <- mqpp.queue:
return
default:
pmqp = &PooledMysqlQueryPiece{
MysqlQueryPiece: MysqlQueryPiece{},
}
return
}
pmqp = mqpp.queue[0]
mqpp.queue = mqpp.queue[1:]
return
}