计数器 #

一、计数器概述 #

1.1 什么是计数器 #

计数器(Counter)是Cassandra中一种特殊的列类型,专门用于分布式计数。

text
计数器特点:

✓ 64位有符号整数
✓ 支持原子递增/递减
✓ 分布式安全
✓ 高性能

1.2 计数器限制 #

text
计数器限制:

表限制
├── 计数器表只能包含主键和计数器列
├── 不能包含其他类型的列
└── 不能设置TTL

操作限制
├── 只能递增/递减
├── 不能直接设置值
└── 不能使用轻量级事务

二、创建计数器表 #

2.1 基本语法 #

sql
CREATE TABLE table_name (
    pk_column data_type,
    counter_column COUNTER,
    ...
    PRIMARY KEY (pk_column)
);

2.2 创建示例 #

sql
-- 用户统计计数器
CREATE TABLE user_counters (
    user_id UUID PRIMARY KEY,
    login_count COUNTER,
    page_views COUNTER,
    purchase_count COUNTER
);

-- 全局统计计数器
CREATE TABLE global_counters (
    counter_name TEXT PRIMARY KEY,
    counter_value COUNTER
);

-- 多维度计数器
CREATE TABLE daily_stats (
    stat_date DATE,
    stat_type TEXT,
    stat_value COUNTER,
    PRIMARY KEY (stat_date, stat_type)
);

三、更新计数器 #

3.1 递增操作 #

sql
-- 递增1
UPDATE user_counters 
SET login_count = login_count + 1
WHERE user_id = ?;

-- 递增指定值
UPDATE user_counters 
SET page_views = page_views + 10
WHERE user_id = ?;

-- 多列递增
UPDATE user_counters 
SET login_count = login_count + 1,
    page_views = page_views + 5,
    purchase_count = purchase_count + 1
WHERE user_id = ?;

3.2 递减操作 #

sql
-- 递减1
UPDATE user_counters 
SET login_count = login_count - 1
WHERE user_id = ?;

-- 递减指定值
UPDATE user_counters 
SET page_views = page_views - 5
WHERE user_id = ?;

3.3 批量更新 #

sql
-- 批量更新计数器
BEGIN COUNTER BATCH
    UPDATE user_counters 
    SET login_count = login_count + 1
    WHERE user_id = ?;
    
    UPDATE global_counters 
    SET counter_value = counter_value + 1
    WHERE counter_name = 'total_logins';
APPLY BATCH;

四、查询计数器 #

4.1 基本查询 #

sql
-- 查询单个计数器
SELECT login_count FROM user_counters 
WHERE user_id = ?;

-- 查询多个计数器
SELECT login_count, page_views, purchase_count 
FROM user_counters 
WHERE user_id = ?;

-- 查询所有计数器
SELECT * FROM user_counters WHERE user_id = ?;

4.2 范围查询 #

sql
-- 按日期范围查询
SELECT * FROM daily_stats 
WHERE stat_date >= '2024-01-01' 
AND stat_date <= '2024-01-31';

-- 按类型查询
SELECT * FROM daily_stats 
WHERE stat_date = '2024-01-15' 
AND stat_type IN ('logins', 'page_views');

五、计数器设计模式 #

5.1 用户维度计数 #

sql
-- 用户行为计数
CREATE TABLE user_behavior_counters (
    user_id UUID,
    behavior_type TEXT,
    count COUNTER,
    PRIMARY KEY (user_id, behavior_type)
);

-- 更新
UPDATE user_behavior_counters 
SET count = count + 1
WHERE user_id = ? AND behavior_type = 'login';

-- 查询
SELECT * FROM user_behavior_counters 
WHERE user_id = ?;

5.2 时间维度计数 #

sql
-- 按天统计
CREATE TABLE daily_counters (
    counter_date DATE,
    counter_name TEXT,
    counter_value COUNTER,
    PRIMARY KEY (counter_date, counter_name)
);

-- 更新
UPDATE daily_counters 
SET counter_value = counter_value + 1
WHERE counter_date = '2024-01-15' 
AND counter_name = 'total_logins';

-- 查询
SELECT * FROM daily_counters 
WHERE counter_date = '2024-01-15';

5.3 分桶计数 #

sql
-- 高并发计数器分桶
CREATE TABLE sharded_counters (
    counter_name TEXT,
    bucket INT,
    counter_value COUNTER,
    PRIMARY KEY (counter_name, bucket)
);

-- 更新(随机选择桶)
UPDATE sharded_counters 
SET counter_value = counter_value + 1
WHERE counter_name = 'page_views' 
AND bucket = ?;  -- 0-99随机

-- 查询总和
SELECT SUM(counter_value) 
FROM sharded_counters 
WHERE counter_name = 'page_views';

六、一致性考虑 #

6.1 一致性级别 #

sql
-- 推荐使用QUORUM
CONSISTENCY QUORUM;

UPDATE user_counters 
SET login_count = login_count + 1
WHERE user_id = ?;

-- 或LOCAL_QUORUM(多数据中心)
CONSISTENCY LOCAL_QUORUM;

6.2 计数精度 #

text
计数精度考虑:

最终一致性
├── 计数器是最终一致的
├── 短期内可能有误差
└── 适合近似计数场景

强一致性
├── 使用QUORUM读写
├── 性能开销大
└── 适合精确计数场景

建议
├── 统计类:ONE即可
├── 业务类:QUORUM
└── 金融类:考虑其他方案

七、性能优化 #

7.1 分桶策略 #

text
分桶策略:

目的
├── 分散热点
├── 提高并发能力
└── 减少锁竞争

实现
├── 确定桶数量(如100)
├── 随机选择桶更新
└── 查询时聚合

适用
├── 高并发计数
├── 全局计数器
└── 热点计数器

7.2 批量更新 #

sql
-- 使用COUNTER BATCH
BEGIN COUNTER BATCH
    UPDATE user_counters SET login_count = login_count + 1 WHERE user_id = uuid1;
    UPDATE user_counters SET login_count = login_count + 1 WHERE user_id = uuid2;
    UPDATE user_counters SET login_count = login_count + 1 WHERE user_id = uuid3;
APPLY BATCH;

八、最佳实践 #

8.1 使用场景 #

text
计数器适用场景:

适合
├── 用户行为统计
├── 页面访问计数
├── 点赞/收藏数
├── 库存计数(非精确)
└── 实时统计

不适合
├── 精确金融计数
├── 需要回滚的计数
├── 需要历史记录
└── 需要事务保证

8.2 设计建议 #

text
设计建议:

1. 独立计数器表
   └── 不要与业务数据混合

2. 合理选择一致性级别
   └── 根据精度需求

3. 高并发使用分桶
   └── 分散写入压力

4. 监控计数器性能
   └── 关注延迟和误差

九、总结 #

计数器要点:

  1. 专用表:计数器表只能包含主键和计数器列
  2. 原子操作:支持原子递增/递减
  3. 一致性选择:根据精度需求选择一致性级别
  4. 分桶优化:高并发场景使用分桶策略
  5. 适用场景:统计类、近似计数场景
  6. 限制明确:不能设置值、不能TTL

下一步,让我们学习TTL过期!

最后更新:2026-03-27