Skip to content

Commit ab74c13

Browse files
authored
Merge branch 'unstable' into fixAcl
2 parents 76140df + 38eb16d commit ab74c13

11 files changed

Lines changed: 6524 additions & 4739 deletions

File tree

.github/workflows/pika.yml

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,20 @@ jobs:
2626
with:
2727
go-version: 1.19
2828

29+
- name: ccache
30+
uses: hendrikmuhs/ccache-action@v1.2.13
31+
with:
32+
key: ubuntu-latest
33+
2934
- name: Install Deps
30-
if: ${{ steps.cache.output.cache-hit != 'true' }}
3135
run: |
3236
sudo apt-get install -y autoconf libprotobuf-dev protobuf-compiler
3337
sudo apt-get install -y clang-tidy-12
3438
3539
- name: Configure CMake
3640
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
3741
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
38-
run: cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DUSE_PIKA_TOOLS=ON -DCMAKE_CXX_FLAGS_DEBUG=-fsanitize=address
39-
40-
- name: Cache Build
41-
uses: actions/cache@v3
42-
id: cache-ubuntu
43-
with:
44-
key: ${{ runner.os }}-build-ubuntu-${{ hashFiles('**/CMakeLists.txt') }}
45-
path: |
46-
${{ github.workspace }}/buildtrees
47-
${{ github.workspace }}/deps
42+
run: cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DUSE_PIKA_TOOLS=ON -DCMAKE_CXX_FLAGS_DEBUG=-fsanitize=address -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache
4843

4944
- name: Build
5045
# Build your program with the given configuration
@@ -166,25 +161,21 @@ jobs:
166161
with:
167162
go-version: 1.19
168163

164+
- name: ccache
165+
uses: hendrikmuhs/ccache-action@v1.2.13
166+
with:
167+
key: macos-12
168+
169169
- name: Install Deps
170170
run: |
171171
brew update
172172
brew install --overwrite python@3.12 autoconf protobuf llvm wget git
173173
brew install gcc@10 automake cmake make binutils
174+
174175
- name: Configure CMake
175176
run: |
176177
export CC=/usr/local/opt/gcc@10/bin/gcc-10
177-
cmake -B build -DCMAKE_C_COMPILER=/usr/local/opt/gcc@10/bin/gcc-10 -DUSE_PIKA_TOOLS=ON -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_FLAGS_DEBUG=-fsanitize=address
178-
179-
- uses: actions/cache@v3
180-
with:
181-
path: ${{ github.workspace }}/deps
182-
key: ${{ runner.os }}-deps-${{ hashFiles('**/CMakeLists.txt') }}
183-
184-
- uses: actions/cache@v3
185-
with:
186-
path: ${{ github.workspace }}/buildtrees
187-
key: ${{ runner.os }}-buildtrees-${{ hashFiles('**/CMakeLists.txt') }}
178+
cmake -B build -DCMAKE_C_COMPILER=/usr/local/opt/gcc@10/bin/gcc-10 -DUSE_PIKA_TOOLS=ON -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_FLAGS_DEBUG=-fsanitize=address -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache
188179
189180
- name: Build
190181
run: |

codis/pkg/proxy/config.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,9 @@ type Config struct {
194194

195195
SlowlogLogSlowerThan int64 `toml:"slowlog_log_slower_than" json:"slowlog_log_slower_than"`
196196

197-
QuickCmdList string `toml:"quick_cmd_list" json:"quick_cmd_list"`
198-
SlowCmdList string `toml:"slow_cmd_list" json:"slow_cmd_list"`
197+
QuickCmdList string `toml:"quick_cmd_list" json:"quick_cmd_list"`
198+
SlowCmdList string `toml:"slow_cmd_list" json:"slow_cmd_list"`
199+
AutoSetSlowFlag bool `toml:"auto_set_slow_flag" json:"auto_set_slow_flag"`
199200

200201
MetricsReportServer string `toml:"metrics_report_server" json:"metrics_report_server"`
201202
MetricsReportPeriod timesize.Duration `toml:"metrics_report_period" json:"metrics_report_period"`

codis/pkg/proxy/proxy.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@ func (p *Proxy) serveProxy() {
555555
log.PanicErrorf(err, "setSlowCmdList [%s] failed", p.config.SlowCmdList)
556556
}
557557

558+
StatsSetLogSlowerThan(p.config.SlowlogLogSlowerThan)
559+
558560
select {
559561
case <-p.exit.C:
560562
log.Warnf("[%p] proxy shutdown", p)
@@ -603,6 +605,16 @@ type Overview struct {
603605
Slots []*models.Slot `json:"slots,omitempty"`
604606
}
605607

608+
type CmdInfo struct {
609+
Total int64 `json:"total"`
610+
Fails int64 `json:"fails"`
611+
Redis struct {
612+
Errors int64 `json:"errors"`
613+
} `json:"redis"`
614+
QPS int64 `json:"qps"`
615+
Cmd []*OpStats `json:"cmd,omitempty"`
616+
}
617+
606618
type Stats struct {
607619
Online bool `json:"online"`
608620
Closed bool `json:"closed"`
@@ -709,7 +721,7 @@ func (p *Proxy) Stats(flags StatsFlags) *Stats {
709721
stats.Ops.Fails = OpFails()
710722
stats.Ops.Redis.Errors = OpRedisErrors()
711723
stats.Ops.QPS = OpQPS()
712-
724+
stats.Ops.Cmd = GetOpStatsByInterval(1)
713725
if flags.HasBit(StatsCmds) {
714726
stats.Ops.Cmd = GetOpStatsAll()
715727
}
@@ -752,3 +764,21 @@ func (p *Proxy) Stats(flags StatsFlags) *Stats {
752764
stats.SlowCmdCount = SlowCmdCount.Int64()
753765
return stats
754766
}
767+
768+
func (s *Proxy) CmdInfo(interval int64) *CmdInfo {
769+
info := &CmdInfo{
770+
Total: OpTotal(),
771+
Fails: OpFails(),
772+
QPS: OpQPS(),
773+
Cmd: GetOpStatsByInterval(interval),
774+
}
775+
info.Redis.Errors = OpRedisErrors()
776+
return info
777+
}
778+
779+
func StatsSetLogSlowerThan(ms int64) {
780+
if ms < 0 {
781+
return
782+
}
783+
cmdstats.logSlowerThan.Set(ms)
784+
}

codis/pkg/proxy/proxy_api.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ func newApiServer(p *Proxy) http.Handler {
6565
r.Get("/model", api.Model)
6666
r.Get("/stats", api.StatsNoXAuth)
6767
r.Get("/slots", api.SlotsNoXAuth)
68+
r.Get("/cmdinfo/:interval", api.CmdInfoNoXAuth)
6869
})
6970
r.Group("/api/proxy", func(r martini.Router) {
7071
r.Get("/model", api.Model)
7172
r.Get("/xping/:xauth", api.XPing)
7273
r.Get("/stats/:xauth", api.Stats)
7374
r.Get("/stats/:xauth/:flags", api.Stats)
75+
r.Get("/cmdinfo/:xauth/:interval", api.CmdInfo)
7476
r.Get("/slots/:xauth", api.Slots)
7577
r.Put("/start/:xauth", api.Start)
7678
r.Put("/stats/reset/:xauth", api.ResetStats)
@@ -115,6 +117,10 @@ func (s *apiServer) SlotsNoXAuth() (int, string) {
115117
return rpc.ApiResponseJson(s.proxy.Slots())
116118
}
117119

120+
func (s *apiServer) CmdInfoNoXAuth() (int, string) {
121+
return rpc.ApiResponseJson(s.proxy.CmdInfo(2))
122+
}
123+
118124
func (s *apiServer) XPing(params martini.Params) (int, string) {
119125
if err := s.verifyXAuth(params); err != nil {
120126
return rpc.ApiResponseError(err)
@@ -123,6 +129,21 @@ func (s *apiServer) XPing(params martini.Params) (int, string) {
123129
}
124130
}
125131

132+
func (s *apiServer) CmdInfo(params martini.Params) (int, string) {
133+
if err := s.verifyXAuth(params); err != nil {
134+
return rpc.ApiResponseError(err)
135+
}
136+
var interval int64
137+
if i := params["interval"]; i != "" {
138+
n, err := strconv.Atoi(i)
139+
if err != nil {
140+
return rpc.ApiResponseError(err)
141+
}
142+
interval = int64(n)
143+
}
144+
return rpc.ApiResponseJson(s.proxy.CmdInfo(interval))
145+
}
146+
126147
func (s *apiServer) Stats(params martini.Params) (int, string) {
127148
if err := s.verifyXAuth(params); err != nil {
128149
return rpc.ApiResponseError(err)
@@ -271,6 +292,15 @@ func (c *ApiClient) Stats(flags StatsFlags) (*Stats, error) {
271292
return stats, nil
272293
}
273294

295+
func (c *ApiClient) CmdInfo(interval int64) (*CmdInfo, error) {
296+
url := c.encodeURL("/api/proxy/cmdinfo/%s/%d", c.xauth, interval)
297+
cmdInfo := &CmdInfo{}
298+
if err := rpc.ApiGetJson(url, cmdInfo); err != nil {
299+
return nil, err
300+
}
301+
return cmdInfo, nil
302+
}
303+
274304
func (c *ApiClient) Slots() ([]*models.Slot, error) {
275305
url := c.encodeURL("/api/proxy/slots/%s", c.xauth)
276306
slots := []*models.Slot{}

codis/pkg/proxy/session.go

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@ package proxy
66
import (
77
"encoding/json"
88
"fmt"
9+
"math/rand"
910
"net"
11+
"pika/codis/v2/pkg/utils"
1012
"strconv"
1113
"strings"
1214
"sync"
1315
"time"
1416

1517
"pika/codis/v2/pkg/models"
1618
"pika/codis/v2/pkg/proxy/redis"
17-
"pika/codis/v2/pkg/utils"
1819
"pika/codis/v2/pkg/utils/errors"
1920
"pika/codis/v2/pkg/utils/log"
2021
"pika/codis/v2/pkg/utils/sync2/atomic2"
@@ -48,6 +49,8 @@ type Session struct {
4849
config *Config
4950
proxy *Proxy
5051

52+
rand *rand.Rand
53+
5154
authorized bool
5255
}
5356

@@ -79,6 +82,7 @@ func NewSession(sock net.Conn, config *Config, proxy *Proxy) *Session {
7982
CreateUnix: time.Now().Unix(),
8083
}
8184
s.stats.opmap = make(map[string]*opStats, 16)
85+
s.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
8286
log.Infof("session [%p] create: %s", s, s)
8387
return s
8488
}
@@ -237,31 +241,35 @@ func (s *Session) loopWriter(tasks *RequestChan) (err error) {
237241
} else {
238242
s.incrOpStats(r, resp.Type)
239243
}
244+
240245
nowTime := time.Now().UnixNano()
241246
duration := int64((nowTime - r.ReceiveTime) / 1e3)
242247
s.updateMaxDelay(duration, r)
243248
if fflush {
244249
s.flushOpStats(false)
245250
}
246-
if duration >= s.config.SlowlogLogSlowerThan {
247-
SlowCmdCount.Incr() // Atomic global variable, increment by 1 when slow log occurs.
248-
//client -> proxy -> server -> porxy -> client
249-
//Record the waiting time from receiving the request from the client to sending it to the backend server
250-
//the waiting time from sending the request to the backend server to receiving the response from the server
251-
//the waiting time from receiving the server response to sending it to the client
252-
var d0, d1, d2 int64 = -1, -1, -1
253-
if r.SendToServerTime > 0 {
254-
d0 = int64((r.SendToServerTime - r.ReceiveTime) / 1e3)
255-
}
256-
if r.SendToServerTime > 0 && r.ReceiveFromServerTime > 0 {
257-
d1 = int64((r.ReceiveFromServerTime - r.SendToServerTime) / 1e3)
258-
}
259-
if r.ReceiveFromServerTime > 0 {
260-
d2 = int64((nowTime - r.ReceiveFromServerTime) / 1e3)
251+
if s.config.SlowlogLogSlowerThan >= 0 {
252+
if duration >= s.config.SlowlogLogSlowerThan {
253+
SlowCmdCount.Incr()
254+
// Atomic global variable, increment by 1 when slow log occurs.
255+
//client -> proxy -> server -> porxy -> client
256+
//Record the waiting time from receiving the request from the client to sending it to the backend server
257+
//the waiting time from sending the request to the backend server to receiving the response from the server
258+
//the waiting time from receiving the server response to sending it to the client
259+
var d0, d1, d2 int64 = -1, -1, -1
260+
if r.SendToServerTime > 0 {
261+
d0 = int64((r.SendToServerTime - r.ReceiveTime) / 1e3)
262+
}
263+
if r.SendToServerTime > 0 && r.ReceiveFromServerTime > 0 {
264+
d1 = int64((r.ReceiveFromServerTime - r.SendToServerTime) / 1e3)
265+
}
266+
if r.ReceiveFromServerTime > 0 {
267+
d2 = int64((nowTime - r.ReceiveFromServerTime) / 1e3)
268+
}
269+
index := getWholeCmd(r.Multi, cmd)
270+
log.Errorf("%s remote:%s, start_time(us):%d, duration(us): [%d, %d, %d], %d, tasksLen:%d, command:[%s].",
271+
time.Unix(r.ReceiveTime/1e9, 0).Format("2006-01-02 15:04:05"), s.Conn.RemoteAddr(), r.ReceiveTime/1e3, d0, d1, d2, duration, r.TasksLen, string(cmd[:index]))
261272
}
262-
index := getWholeCmd(r.Multi, cmd)
263-
log.Errorf("%s remote:%s, start_time(us):%d, duration(us): [%d, %d, %d], %d, tasksLen:%d, command:[%s].",
264-
time.Unix(r.ReceiveTime/1e9, 0).Format("2006-01-02 15:04:05"), s.Conn.RemoteAddr(), r.ReceiveTime/1e3, d0, d1, d2, duration, r.TasksLen, string(cmd[:index]))
265273
}
266274
return nil
267275
})
@@ -681,32 +689,67 @@ func (s *Session) handleRequestSlotsMapping(r *Request, d *Router) error {
681689
}
682690
}
683691

684-
func (s *Session) incrOpTotal() {
685-
s.stats.total.Incr()
686-
}
692+
func (s *Session) getOpStats(opstr string, create bool) *opStats {
693+
var (
694+
ok bool
695+
stat *opStats
696+
)
687697

688-
func (s *Session) getOpStats(opstr string) *opStats {
689-
e := s.stats.opmap[opstr]
690-
if e == nil {
691-
e = &opStats{opstr: opstr}
692-
s.stats.opmap[opstr] = e
698+
func() {
699+
cmdstats.opmapLock.RLock()
700+
defer cmdstats.opmapLock.RUnlock()
701+
stat, ok = s.stats.opmap[opstr]
702+
}()
703+
if (ok && stat != nil) || !create {
704+
return stat
705+
}
706+
cmdstats.opmapLock.Lock()
707+
defer cmdstats.opmapLock.Unlock()
708+
stat, ok = cmdstats.opmap[opstr]
709+
if ok && stat != nil {
710+
return stat
711+
}
712+
stat = &opStats{opstr: opstr}
713+
for i := 0; i < IntervalNum; i++ {
714+
stat.delayInfo[i] = &delayInfo{interval: IntervalMark[i]}
693715
}
694-
return e
716+
s.stats.opmap[opstr] = stat
717+
718+
return stat
695719
}
696720

697721
func (s *Session) incrOpStats(r *Request, t redis.RespType) {
698-
e := s.getOpStats(r.OpStr)
699-
e.calls.Incr()
700-
e.nsecs.Add(time.Now().UnixNano() - r.ReceiveTime)
722+
if r == nil {
723+
return
724+
}
725+
responseTime := time.Now().UnixNano() - r.ReceiveTime
726+
var (
727+
ok bool
728+
stat *opStats
729+
)
730+
stat, ok = s.stats.opmap[r.OpStr]
731+
if !ok || stat == nil {
732+
stat = getOpStats(r.OpStr, true)
733+
s.stats.opmap[r.OpStr] = stat
734+
}
735+
stat.incrOpStats(responseTime, redis.RespType(t))
736+
stat, ok = s.stats.opmap["ALL"]
737+
if !ok || stat == nil {
738+
stat = getOpStats("ALL", true)
739+
s.stats.opmap["ALL"] = stat
740+
}
741+
stat.incrOpStats(responseTime, redis.RespType(t))
742+
stat.calls.Incr()
743+
stat.nsecs.Add(time.Now().UnixNano() - r.ReceiveTime)
701744
switch t {
702745
case redis.TypeError:
703-
e.redis.errors.Incr()
746+
incrOpRedisErrors()
704747
}
705748
}
706749

707750
func (s *Session) incrOpFails(r *Request, err error) error {
708751
if r != nil {
709-
e := s.getOpStats(r.OpStr)
752+
e := s.getOpStats(r.OpStr, true)
710753
e.fails.Incr()
711754
} else {
712755
s.stats.fails.Incr()
@@ -781,7 +824,7 @@ func (s *Session) handlePConfig(r *Request) error {
781824
}
782825

783826
func (s *Session) updateMaxDelay(duration int64, r *Request) {
784-
e := s.getOpStats(r.OpStr) // There is no race condition in the session
827+
e := s.getOpStats(r.OpStr, true) // There is no race condition in the session
785828
if duration > e.maxDelay.Int64() {
786829
e.maxDelay.Set(duration)
787830
}

0 commit comments

Comments
 (0)