You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

92 lines
2.9 KiB

package analyze
import (
"fmt"
"sync/atomic"
"time"
"yunyan/utils"
)
// statLoc 统计日界时区,由模块 Init 经 setStatLoc 写入(默认 Asia/Shanghai)。
// 埋点(Report)与同步(sync)两侧共用,保证 0 点切日口径一致;未初始化时回退固定 UTC+8。
var statLoc atomic.Value // *time.Location
func setStatLoc(loc *time.Location) { statLoc.Store(loc) }
func statLocation() *time.Location {
if v := statLoc.Load(); v != nil {
return v.(*time.Location)
}
return time.FixedZone("UTC+8", 8*3600)
}
// dayNumber 把时间转成 YYYYMMDD 形式的统计日(按固定统计时区,跨部署口径一致)。
func dayNumber(t time.Time) uint32 {
return utils.StatDayNumber(t, statLocation())
}
// ============================ Redis 键 ============================
// keyPrefix 形如 {集群标签}:analyze:{应用ID}:{区域},由 setupKeys 写入;
// 多集群 / 多应用 / 多区域共用一套 Redis 时互不串台。
// 用 atomic 保证 setupKeys(启动期) 与 Report(运行期) 间无竞态。
var keyPrefix atomic.Value // string
func prefix() string {
if p := keyPrefix.Load(); p != nil {
return p.(string)
}
return ""
}
// indexKey 活跃统计分区的索引集合:成员为 "产品ID:统计日"。
func indexKey() string { return prefix() + ":idx" }
// hashKey 某 [产品×日] 累加计数的哈希。
func hashKey(productId, statDay uint32) string {
return fmt.Sprintf("%s:%d:%d", prefix(), productId, statDay)
}
// hllKey 某 [产品×日] 某去重指标的 HyperLogLog。
func hllKey(productId, statDay uint32, metric string) string {
return fmt.Sprintf("%s:%d:%d:u:%s", prefix(), productId, statDay, metric)
}
// partition 索引集合的成员,标识一个 产品:日 分区。
func partition(productId, statDay uint32) string {
return fmt.Sprintf("%d:%d", productId, statDay)
}
// 统计哈希的字段名,与 stats_global_day 表列名保持一致,便于追溯。
const (
fLoginCount = "login_count"
fNewUserCount = "new_user_count"
fActiveDeviceCount = "active_device_count"
fBindDeviceCount = "bind_device_count"
fQRActiveCount = "qr_active_count"
fOrderCreateCount = "order_create_count"
fOrderPaidCount = "order_paid_count"
fOrderFailedCount = "order_failed_count"
fOrderCreateAmount = "order_create_amount"
fOrderPaidAmount = "order_paid_amount"
fGrantVipDay = "grant_vip_day"
fGrantAiIntegral = "grant_ai_integral"
fGrantTradeSecond = "grant_trade_second"
fGrantMeetSecond = "grant_meet_second"
fAiChatCount = "ai_chat_count"
fAiUpToken = "ai_up_token"
fAiDownToken = "ai_down_token"
fTradeCount = "trade_count"
fTradeSecond = "trade_second"
fTradeWords = "trade_words"
fMeetCount = "meet_count"
fMeetSecond = "meet_second"
)
// 去重指标的 HLL 名(对应 stats_global_day 的 *_user_count 列)。
const (
uLogin = "login"
uActive = "active"
uPay = "pay"
)