Redis 性能优化选择:Pika 的配置与使用详解

引言

在我们日常开发中 redis是我们开发业务场景中不可缺少的部分。Redis 凭借其内存存储和快速响应的特点,广泛应用于缓存、消息队列等各种业务场景。然而,随着数据量的不断增长,单节点的 Redis 因为内存限制和并发能力的局限,逐渐难以支撑高并发的请求。为了解决这些问题,我们通常会采用 搭建Redis 集群方案来解决高并发下的限制问题。然而,Redis 集群的部署往往需要更高的资源投入,巨大的内存需求和运维成本带来了不小的压力。除此之外,集群模式下的数据分片和一致性问题,也让系统设计的复杂度大大增加。

在这种高并发、大流量的业务场景下,我们是否能够在追求 Redis 高性能的同时,找到更经济高效的大数据解决方案呢?除了 Redis 集群方案外,今天我将介绍一种可以替代 Redis 集群的方案,也是我在以往开发中广泛使用的一种数据结构------Pika。Pika 在兼容 Redis API 的基础上,将数据存储在磁盘上,突破了内存限制,尤其适合大数据存储和高并发访问的需求。


什么是 Pika?

Pika 是一种兼容 Redis 协议的高效存储引擎,设计初衷就是为了解决 Redis 在大数据场景下因内存限制而带来的瓶颈问题。与 Redis 将数据存储在内存中的方式不同,Pika 将数据存储在磁盘上,从而有效扩展存储容量,适应大规模数据的需求。当 Redis 的内存使用量超过 16 GiB 时,会面临多种限制,如内存容量受限、单线程阻塞、启动恢复时间长、内存硬件成本高、缓冲区容易填满、一主多从故障时的切换成本高等。Pika 的出现并非为了替代 Redis,而是为了补充 Redis ,以便在大数据场景下依然保持高性能。Pika 力求完全遵守 Redis 协议,继承 Redis 便捷的运维设计,同时通过持久化存储来突破 Redis 在数据量巨大时内存容量不足的瓶颈。此外,Pika 支持通过 slaveof 命令进行主从模式配置,支持全量和增量数据同步,方便在大数据和高可用场景下的灵活扩展。

Pika 的兼容性

Pika 兼容 Redis 中的 stringhashlistzsetset 五大核心数据类型,能够支持大部分与之相关的操作接口(兼容详情可查阅官方文档),实现了几乎所有 Redis 的基本操作需求。这意味着,现有的 Redis 客户端和命令都可以无缝迁移到 Pika 上使用,无需额外学习新的命令或语法。

Pika 的主从备份能力

与 Redis 一样,Pika 支持通过 slaveof 命令进行主从复制,提供可靠的备份和高可用性支持。同时,Pika 实现了全同步和部分同步机制,能够在数据同步中做到既灵活又高效,确保数据一致性和稳定性。这样,Pika 既保留了 Redis 数据复制的优势,又在容量上扩展了存储空间,可以在不更改代码的前提下快速接入生产环境。

为什么选择 Pika?

Pika 提供了与 Redis 一致的使用体验,且不需要额外的学习和开发成本。相较于 Redis,Pika 的优势体现在以下几方面:

  1. 更大的存储容量:Pika 通过磁盘存储解决了 Redis 的内存瓶颈问题,适合大规模数据场景。
  2. 无缝替换:Pika 兼容 Redis 绝大多数核心命令,因此在功能实现和操作上与 Redis 几乎无异,用户不必更改现有代码或熟悉新的命令,即可将 Pika 集成到现有系统中。
  3. 高可用性和备份支持:Pika 支持主从复制、全同步和部分同步,确保数据可靠性和高并发访问。

Pika 的适用场景

Pika 的设计非常适合以下几种高容量、高并发的数据场景:

  1. 大数据量缓存:对于数据规模庞大的应用,比如实时数据处理、日志收集和分析场景,Pika 的磁盘存储使它能轻松应对 TB 级数据,不再受限于内存容量。适用于金融、广告、物联网等需要存储大量实时数据的行业。
  2. 高并发访问场景:在流量密集型业务中,如电商、游戏和社交网络,Pika 能够支持高并发访问需求,与 Redis 一样实现快速的数据读写,但在资源消耗上更经济。
  3. 长时间数据存储:在日志存储、历史数据存储等业务中,数据需要长时间保留,但访问频率相对较低。Pika 的磁盘持久化存储方式为此类场景提供了低成本的替代方案,不会因数据量增加而导致内存压力上升。
  4. 分布式集群环境:对于需要高可用性的数据集群应用,Pika 的主从复制和同步功能使其可以在分布式环境中稳定运行,支持多节点备份和容灾切换,确保数据的高可靠性和一致性。

Pika使用用户

Pika 已被各大公司广泛采用,用于内部部署,证明了其可扩展性和可靠性。一些值得注意的使用实例包括:

  • 360公司:内部部署,规模10000+实例,单机数据量1.8TB。
  • 微博:内部部署,有10000+个实例。
  • 喜马拉雅(Xcache) :6000+实例,海量数据超过120TB。
  • 个推 公司:内部部署,300+实例,累计数据量超过30TB。

此外,迅雷、小米、知乎、好未来、快手、搜狐、美团、脉脉等公司也在使用 Pika。有关完整用户列表,可以参考 Pika 项目提供的官方列表。

这些在不同公司和行业的部署凸显了 Pika 在处理大规模、大容量数据存储需求方面的适应性和有效性。


接下来,我将展示如何安装 Pika,并进行简单的使用示例,以便快速上手并体验 Pika 的性能。

安装之前我们先看下官方给的安装示例:安装示例

我按照官方的安装示例 安装的是v4.0.1最新版本及之前版本。但是我一直未make或build成功。不知道是不是我自己环境的问题。

本文章采用下载安装包的形式来安装
  1. 首先我们去版本库下载对应版本的安装包(我选择是v3.3.0

  2. 将安装包上传到 /usr/local/pika 目录中,便于管理:

    bash 复制代码
    sudo mkdir -p /usr/local/pika
  3. 然后解压该安装包

    bash 复制代码
    sudo tar -xvf  pika-linux-x86_64-v3.3.0.tar.bz2 
  4. 解压完成后会生成一个output文件夹,接下来我们执行命令启动

    bash 复制代码
       ./output/bin/pika -c ./output/conf/pika.confb
  5. 我第一次启动报错了 报错如下:

    • 这个错误提示主要有两个原因:1. Rsync 失败pika_rsync_service.cc:48 报错提示无法启动 rsync 服务,可能是 rsync 没有安装或者路径配置有问题。

      1. 端口绑定失败 :提示 bind port 10221 failed,表示 Pika 无法绑定端口 10221,可能是端口被占用,或者当前用户权限不足。
    • Pika 使用 rsync 进行数据同步,请确保系统已安装 rsync

      bash 复制代码
      sudo yum install -y rsync

      安装完成后,重新尝试启动 Pika。

    • 使用以下命令检查是否有其他进程占用了 10221 端口:

      bash 复制代码
      sudo lsof -i :10221

      如果有其他进程占用端口,可以尝试停止占用端口的进程,或者更改 Pika 的端口配置。

解决上面问题后 我尝试重新启动,可以看到已经成功启动:

启动成功后我们另开一个窗口来测试操作简单命令:


我们来大概看下安装的Pika配置文件 在output/conf下的pika.conf:

conf 复制代码
# Pika port
port : 9221  # Pika 监听的端口

# Thread Number
thread-num : 1  # 用于处理客户端请求的工作线程数

# Thread Pool Size
thread-pool-size : 12  # 线程池大小,用于处理并发任务

# Sync Thread Number
sync-thread-num : 6  # 用于主从同步的线程数

# Pika log path
log-path : ./log/  # 日志文件的存储路径

# Pika db path
db-path : ./db/  # 数据库文件的存储路径

# Pika write-buffer-size
write-buffer-size : 268435456  # 写缓冲区大小,单位为字节(256MB)

# Pika timeout
timeout : 60  # 客户端连接空闲超时时间,单位为秒

# Requirepass
requirepass :  # 设置管理员密码,用于验证高权限操作

# Masterauth
masterauth :  # 从节点连接主节点时的认证密码

# Userpass
userpass :  # 普通用户连接的密码

# User Blacklist
userblacklist :  # 黑名单用户列表,拒绝指定用户访问

# Pika instance mode [classic | sharding]
instance-mode : classic  # Pika 的实例模式:classic 为多数据库模式,sharding 为分片模式

# Set the number of databases. Limited in [1, 8]
databases : 1  # 数据库数量,仅在 classic 模式下有效

# default slot number each table in sharding mode
default-slot-num : 1024  # 每张表的分片数量,仅在 sharding 模式下有效

# replication num defines followers in a single raft group, limited in [0, 4]
replication-num : 0  # Raft 组中的从节点数量

# consensus level defines confirms before commit to client
consensus-level : 0  # 主节点提交前需要的确认数量,用于 Raft 一致性协议

# Dump Prefix
dump-prefix :  # 导出文件的前缀,用于数据持久化文件命名

# daemonize  [yes | no]
#daemonize : yes  # 是否以守护进程方式运行(后台运行)

# Dump Path
dump-path : ./dump/  # 数据导出路径

# Expire-dump-days
dump-expire : 0  # 数据导出的过期天数(0 表示不过期)

# pidfile Path
pidfile : ./pika.pid  # Pika 进程 ID 文件路径

# Max Connection
maxclients : 20000  # 最大客户端连接数

# the per file size of sst to compact, default is 20M
target-file-size-base : 20971520  # 每个 SST 文件的目标大小(20MB)

# Expire-logs-days
expire-logs-days : 7  # 日志文件的过期天数

# Expire-logs-nums
expire-logs-nums : 10  # 日志文件的最大数量

# Root-connection-num
root-connection-num : 2  # root 用户的最大连接数

# Slowlog-write-errorlog
slowlog-write-errorlog : no  # 慢查询日志是否写入错误日志文件

# Slowlog-log-slower-than
slowlog-log-slower-than : 10000  # 慢查询记录的时间阈值,单位为微秒

# Slowlog-max-len
slowlog-max-len : 128  # 慢查询日志的最大条数

# Pika db sync path
db-sync-path : ./dbsync/  # 数据同步文件的存储路径

# db sync speed(MB) max is set to 1024MB, min is set to 0
db-sync-speed : -1  # 主从同步的最大速度,单位为 MB/s,-1 表示无限制

# The slave priority
slave-priority : 100  # 从节点的优先级

# network interface
#network-interface : eth1  # 网络接口(可以指定特定的网卡)

# replication
#slaveof : master-ip:master-port  # 设置为从节点并指定主节点地址和端口

# CronTask, e.g., 02-04/60 for compaction between 2-4am every day
#compact-cron : 3/02-04/60  # 压缩任务计划:在每周三的 2-4 点进行压缩

# Compact-interval, e.g., 6/60 checks compaction every 6 hours
#compact-interval :  # 压缩间隔,单位为小时。比 compact-cron 优先

# sync window size for binlog between master and slave, default is 9000
sync-window-size : 9000  # 主从同步的 binlog 窗口大小

# max connection read buffer size, default is 256MB
max-conn-rbuf-size : 268435456  # 最大读取缓冲区大小

###################
## Critical Settings
###################
# write_binlog  [yes | no]
write-binlog : yes  # 是否开启 binlog 日志记录

# binlog file size: default is 100M,  limited in [1K, 2G]
binlog-file-size : 104857600  # binlog 文件大小限制(100MB)

# Use cache to store up to 'max-cache-statistic-keys' keys
max-cache-statistic-keys : 0  # 缓存的统计键的最大数量,0 表示关闭此功能

# Trigger small compaction after deleting/overwriting keys
small-compaction-threshold : 5000  # 触发小压缩的操作次数阈值

# Flush triggered if all live memtables exceed this limit
max-write-buffer-size : 10737418240  # 所有 memtables 的总内存大小上限(10GB)

# Limit some command response size
max-client-response-size : 1073741824  # 限制响应大小的最大值(1GB)

# Compression type supported [snappy, zlib, lz4, zstd]
compression : snappy  # 数据压缩类型

# max-background-flushes: default is 1, limited in [1, 4]
max-background-flushes : 1  # 后台刷新任务的最大数量

# max-background-compactions: default is 2, limited in [1, 8]
max-background-compactions : 2  # 后台压缩任务的最大数量

# Maximum cached open file descriptors
max-cache-files : 5000  # 缓存的最大打开文件描述符数量

# max_bytes_for_level_multiplier: default is 10, can change to 5
max-bytes-for-level-multiplier : 10  # RocksDB 层次的最大字节数乘数

# BlockBasedTable block_size, default 4k
# block-size: 4096  # 块表的块大小(4KB)

# block LRU cache, default 8M, 0 to disable
# block-cache: 8388608  # LRU 块缓存大小(8MB)

# whether the block cache is shared among RocksDB instances
# share-block-cache: no  # 是否在多个 RocksDB 实例之间共享块缓存

# whether index and filter blocks are in block cache
# cache-index-and-filter-blocks: no  # 是否将索引和过滤块放入块缓存

# bloomfilter of the last level will not be built if set to yes
# optimize-filters-for-hits: no  # 是否优化最后一层的布隆过滤器

# Enables dynamic levels target size for compaction
# level-compaction-dynamic-level-bytes: no  # 是否启用动态级别的压缩目标大小

根据配置文件的配置项可以根据自己的需求更改


在每次启动时手动执行启动命令既麻烦又不便于管理。为此,我们可以通过 Systemd 配置一个服务,使 Pika 开机自启并便于系统控制,提升管理效率。

配置启动服务

  1. 创建 Pika 系统用户

    为了提高安全性,创建一个专用的系统用户和用户组来运行 Pika(在/usr/local/pika下执行):

    bash 复制代码
    sudo groupadd --system pika
    sudo useradd -M -s /sbin/nologin -g pika -d /usr/local/pika pika
  2. 设置文件拥有者

    bash 复制代码
    chown -R pika:pika output
  3. 配置 Pika 作为 Systemd 服务

    /usr/lib/systemd/system 目录下创建 pika.service 文件:

    bash 复制代码
    cat > /usr/lib/systemd/system/pika.service <<EOF
    
    [Unit]
    Description=pika server
    Requires=network.target
    After=network.target
    
    [Service]
    User=pika
    Group=pika
    Type=forking
    WorkingDirectory=/usr/local/pika/output
    ExecStart=/usr/local/pika/output/bin/pika -c /usr/local/pika/output/conf/pika.conf
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    EOF

    确保 WorkingDirectory 路径是有效的目录,并且已经在系统中正确创建。根据您之前的路径配置,将 WorkingDirectory 修改为实际存在的路径,例如:WorkingDirectory=/usr/local/pika/pika-v4.0.1

    ExecStart=/usr/local/pika/pika-v4.0.1-alpha/output/pika -c /usr/local/pika/pika-v4.0.1-alpha/conf/pika.conf

  4. 增加文件描述符限制

    为确保高并发场景下的稳定性,增加文件描述符的限制:

  • 创建 pika.service.d 目录:

    bash 复制代码
    sudo mkdir -p /etc/systemd/system/pika.service.d
  • 在该目录下创建 limit.conf 文件:

    bash 复制代码
    sudo cat > /etc/systemd/system/pika.service.d/limit.conf <<EOF 
    [Service] 
    LimitNOFILE=65536 
    EOF
  1. 启动和管理 Pika 服务

    完成配置后,可以使用以下命令来管理 Pika:

    bash 复制代码
    # 重新加载 systemd 配置文件
    sudo systemctl daemon-reload 
    
    # 启动 Pika 服务 
    sudo systemctl start pika
    
    # 设置 Pika 开机启动 
    sudo systemctl enable pika 
    
    # 检查服务状态 
    sudo systemctl status pika

通过以上步骤,Pika 已成功安装并配置为 systemd 服务,支持自动启动、停止和重启管理,方便在生产环境中使用。这样不仅简化了管理,还提高了服务的稳定性。


注意事项

在安装和配置 Pika 后,以下几点是需要特别注意的,以便更好地理解 Pika 的使用场景和性能表现:

  1. 线程模型

    Pika 是多线程设计,不同于 Redis 的单线程模型,这使得 Pika 能在大多数多核 CPU 环境下有效地处理更多的并发请求。这种设计更适合于大量数据的场景,尤其是在持久化存储需求强烈的场合。

  2. 适用场景

    • 大数据、高容量场景:Pika 在大数据和持久化存储的场景下更具优势。例如,当 Redis 内存超出 16GB 后可能出现瓶颈,Pika 则通过将数据存储在磁盘上而不依赖于内存,有效解决了存储容量的限制问题。
    • 写密集型操作:在写密集型操作时,Pika 的多线程设计使其在高并发写入场景中表现更优。
  3. 性能限制

    虽然 Pika 在某些场景下优于 Redis,但它并非在所有情况下都优于 Redis,也不能完全取代 Redis。在高性能内存操作和极低延迟需求的场景下,例如高速缓存、实时性极高的操作,Redis 的内存操作速度更具优势。

  4. 主从同步和故障恢复

    Pika 支持通过 slaveof 命令配置主从关系,但其同步机制依赖于磁盘 I/O,可能会导致与 Redis 相比稍微较慢的同步速度。对于高频数据变更或对数据实时性要求较高的场景,可能仍需要 Redis 提供更快的响应。

  5. 存储开销

    因为 Pika 依赖磁盘存储,所以需要保证存储空间充足并定期清理过期数据。过大的数据集可能会导致磁盘 I/O 增加,从而对系统的整体性能产生影响。

  6. 选择依据

    Pika 并不是 Redis 的完全替代品。在决定使用 Pika 或 Redis 时,最好结合业务场景:如果数据量较小且关注内存操作的速度,Redis 更合适;而在持久化需求高、数据量大或关注磁盘存储扩展性的场景下,Pika 更适用。


最后

Pika 作为一种兼容 Redis 协议的高效存储引擎,在大数据和持久化存储需求的业务场景中,为 Redis 用户提供了一个强有力的补充方案。Pika 通过将数据存储在磁盘上,有效突破了 Redis 在内存容量上的限制,同时保持了 Redis 的高效操作体验和简便的管理特性。得益于多线程设计,Pika 能在写密集和大容量场景中表现优异,尤其适合那些对数据持久化、扩展性要求较高的场合。

然而,Pika 并非 Redis 的完全替代品。在需要极低延迟、以缓存为核心的场景中,Redis 仍然具备不可替代的优势。因此,选择 Pika 或 Redis 需要结合具体的业务需求,权衡各自的优缺点。总体而言,Pika 在特定的应用场景下能够发挥重要作用,是 Redis 在大数据场景中的有益补充。希望通过本次配置和使用指南,大家能够更好地理解 Pika 的特性和适用性,为项目需求提供更高效的解决方案。

相关推荐
装不满的克莱因瓶几秒前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
梦想平凡2 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
TianyaOAO2 小时前
mysql的事务控制和数据库的备份和恢复
数据库·mysql
Ewen Seong2 小时前
mysql系列5—Innodb的缓存
数据库·mysql·缓存
码农老起3 小时前
企业如何通过TDSQL实现高效数据库迁移与性能优化
数据库·性能优化
java_heartLake3 小时前
Vue3之性能优化
javascript·vue.js·性能优化
arnold663 小时前
探索 ElasticSearch:性能优化之道
大数据·elasticsearch·性能优化
夏木~4 小时前
Oracle 中什么情况下 可以使用 EXISTS 替代 IN 提高查询效率
数据库·oracle
W21554 小时前
Liunx下MySQL:表的约束
数据库·mysql
黄名富4 小时前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua