zoukankan      html  css  js  c++  java
  • Redis入门

    redis基础

    官网地址:https://redis.io/

    Redis和Memcached是非关系型数据库也称为NoSQL数据库

    MySQL、Mariadb、SQL Server、PostgreSQL、Oracle 数据库属于关系型数据(RDBMS, Relational Database Management System)

    redis 简介

    Redis(Remote Dictionary Server)在 2009 年发布,开发者 Salvatore Sanfilippo 是意大利开发者,他本想为自己的公司开发一个用于替换 MySQL 的产品 Redis,但是没有想到他把 Redis 开源后大受欢迎,短短几年,Redis 就有了很大的用户群体,目前国内外使用的公司有知乎网、新浪微博、GitHub 等redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库,redis 提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcache,但相比Memcache,redis 还提供了易扩展、高性能、具备数据持久性等功能。Redis 在高并发、低延迟环境要求比较高的环境使用量非常广泛,目前 redis 在 DB-Engine 月排行榜https://db-engines.com/en/ranking 中一直比较靠前,而且一直是键值型存储类的首位。

    redis 对比 memcached

    支持数据的持久化:可以将内存中的数据保持在磁盘中,重启 redis 服务或者服务器之后可以从备份文件中恢复数据到内存继续使用。

    支持更多的数据类型:支持 string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zet(有序集合)

    支持数据的备份:可以实现类似于数据的 master-slave 模式的数据备份,另外也支持使用快照+AOF。

    支持更大的value数据:memcache 单个key value最大只支持 1MB,而 redis 最大支持 512MB。

    Redis 是单线程,而 memcache 是多线程,所以单机情况下没有 memcache 并发高,但 redis 支持分布式集群以实现更高的并发,单 Redis 实例可以实现数万并发。

    支持集群横向扩展:基于 redis cluster 的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性。

    都是基于 C 语言开发。

    redis 典型应用场景

    Session 共享:常见于 web 集群中的 Tomcat 或者 PHP 中多 web 服务器 session 共享

    消息队列:ELK 的日志缓存、部分业务的订阅发布系统

    计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景

    缓存:数据查询、电商网站商品信息、新闻内容

    微博/微信社交场合:共同好友、点赞评论等

    Redis 安装及使用

    官方下载地址:http://download.redis.io/releases/

    yum安装redis

    centos 系统上安装阿里云epel源

    cd /etc/yum.repos.d/
    wget http://mirrors.aliyun.com/repo/epel-7.repo
    wget http://mirrors.aliyun.com/repo/Centos-7.repo
    

    查看yum仓库redis 版本

    [root@master107 ~]#yum list redis
    Loaded plugins: fastestmirror, langpacks
    Repository base is listed more than once in the configuration
    Repository epel is listed more than once in the configuration
    Repository epel-debuginfo is listed more than once in the configuration
    Repository epel-source is listed more than once in the configuration
    Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
    Loading mirror speeds from cached hostfile
     * base: mirrors.aliyun.com
     * extras: mirrors.aliyun.com
     * updates: mirrors.aliyun.com
    Available Packages
    redis.x86_64              3.2.12-2.el7       epel
    

    安装redis

    yum install redis -y
    systemctl start redis&&systemctl enable redis
    redis-cli
    
    127.0.0.1:6379> info
    # Server
    redis_version:3.2.12
    redis_git_sha1:00000000
    redis_git_dirty:0
    redis_build_id:7897e7d0e13773f
    redis_mode:standalone
    os:Linux 3.10.0-957.el7.x86_64 x86_64
    arch_bits:64
    multiplexing_api:epoll
    gcc_version:4.8.5
    process_id:9307
    run_id:cb416711ff1da3a0399b27f9efbc68b3ec744262
    tcp_port:6379
    uptime_in_seconds:11
    uptime_in_days:0
    hz:10
    lru_clock:8490210
    executable:/usr/bin/redis-server
    config_file:/etc/redis.conf
    
    # Clients
    connected_clients:1
    client_longest_output_list:0
    client_biggest_input_buf:0
    blocked_clients:0
    
    # Memory
    used_memory:813448
    used_memory_human:794.38K
    used_memory_rss:2527232
    used_memory_rss_human:2.41M
    used_memory_peak:813448
    used_memory_peak_human:794.38K
    total_system_memory:8182038528
    total_system_memory_human:7.62G
    used_memory_lua:37888
    used_memory_lua_human:37.00K
    maxmemory:0
    maxmemory_human:0B
    maxmemory_policy:noeviction
    mem_fragmentation_ratio:3.11
    mem_allocator:jemalloc-3.6.0
    
    # Persistence
    loading:0
    rdb_changes_since_last_save:0
    rdb_bgsave_in_progress:0
    rdb_last_save_time:1602325719
    rdb_last_bgsave_status:ok
    rdb_last_bgsave_time_sec:-1
    rdb_current_bgsave_time_sec:-1
    aof_enabled:0
    aof_rewrite_in_progress:0
    aof_rewrite_scheduled:0
    aof_last_rewrite_time_sec:-1
    aof_current_rewrite_time_sec:-1
    aof_last_bgrewrite_status:ok
    aof_last_write_status:ok
    
    # Stats
    total_connections_received:1
    total_commands_processed:1
    instantaneous_ops_per_sec:0
    total_net_input_bytes:31
    total_net_output_bytes:9928
    instantaneous_input_kbps:0.00
    instantaneous_output_kbps:0.00
    rejected_connections:0
    sync_full:0
    sync_partial_ok:0
    sync_partial_err:0
    expired_keys:0
    evicted_keys:0
    keyspace_hits:0
    keyspace_misses:0
    pubsub_channels:0
    pubsub_patterns:0
    latest_fork_usec:0
    migrate_cached_sockets:0
    
    # Replication
    role:master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    # CPU
    used_cpu_sys:0.04
    used_cpu_user:0.01
    used_cpu_sys_children:0.00
    used_cpu_user_children:0.00
    
    # Cluster
    cluster_enabled:0
    
    # Keyspace
    127.0.0.1:6379>
    

    编译安装redis

    创建redis用户和数据目录

    groupadd -g 1000 redis && useradd -u 1000 -g 1000 redis -s /sbin/nologin
    mkdir /data/redis/{conf,logs,data} -p
    chown redis.redis -R /data/redis/
    

    编译安装

    yum install gcc -y
    wget https://download.redis.io/releases/redis-5.0.3.tar.gz
    tar xf redis-5.0.3.tar.gz -C /data/
    cd /data/redis-5.0.3
    make MALLOC=libc PREFIX=/data/redis install
    cp -rp /data/redis-5.0.3/redis.conf /data/redis/conf
    

    修改一下linux系统参数

    vim /etc/sysctl.conf
    net.core.somaxconn = 512
    vm.overcommit_memory = 1
    
    sysctl -p 
    
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    
    修改说明:
    1、net.core.somaxconn = 512
    backlog 参数控制的是三次握手的时候 server 端收到 client ack 确认号之后的队列值。
    
    2、vm.overcommit_memory = 1
    0、表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
    1、表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    2、表示内核允许分配超过所有物理内存和交换空间总和的内存
    
    3、echo never > /sys/kernel/mm/transparent_hugepage/enabled
    开启大页内存动态分配,需要关闭让redis负责内存管理。
    

    编辑service启动

    cat /usr/lib/systemd/system/redis.service
    [Unit]
    Description=Redis persistent key-value database
    After=network.target
    After=network-online.target
    Wants=network-online.target
    [Service]
    ExecStart=/data/redis/bin/redis-server /data/redis/conf/redis.conf --supervised systemd
    ExecReload=/bin/kill -s HUP $MAINPID 
    ExecStop=/bin/kill -s QUIT $MAINPID
    Type=notify
    User=root
    Group=root
    RuntimeDirectory=redis
    RuntimeDirectoryMode=0755
    [Install]
    WantedBy=multi-user.target
    

    创建软链接

    ln -sv /data/redis/bin/redis-* /usr/bin/
    

    启动

    systemctl start redis
    ss -ntl|grep 6379 # 查看端口是否存在
    

    编译出来的工具说明

    redis-benchmark #redis 性能测试工具
    redis-check-aof #AOF 文件检查工具
    redis-check-rdb #RDB 文件检查工具
    redis-cli 		#redis #客户端工具
    redis-sentinel 	#哨兵,连接到server
    redis-server 	#redis 服务端
    

    基本操作命令

    判断key是否存在,0不存在,1存在
    EXISTS k
    
    删除
    DEL k
    
    字符串操作
        单个key操作
        SET k v
        GET k
    
        多个key操作
        MSET k1 v1 k2 v2 k3 v3
        MGET k1 k2 k3
        
        追加数据
        APPEND k1 append
        
        返回字符串 key 长度
        STRLEN k1
    
    查看key的类型
    TYPE k
    
    计时器
    INCR k       #自增1
    INCRBY k 100 #加100
    
    数据递减
    DECR k
     
    
    设置过期时间
    EXPIRE k2 10 #10过期,并删除
    TTL k2       #-2无此key -1无期限 number剩余秒
    PERSIST k    #取消过期时间
    
    列表
        添加列表元素
        RPUSH list 3 #右边添加
        LPUSH list 4 #左边
    
        删除元素
        RPOP list #右边删
        LPOP list #左边删
    
        列表长度
        LLEN list
    
        查看列表中元素
        LRANGE list 0 -1
    
    集合:Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
    	生成集合
    	SADD set1 v1
    	SADD set2 v2 v4
    	
    	追加数值:追加的时候不能追加已经存在的数值
    	SADD set1 v2 v3 v4
    	
    	查看集合的所有数据
    	SMEMBERS set1
    	
    	获取集合的差集:已属于A而不属于B的元素称为A与B的差(集)
    	SDIFF A B
    	
    	获取集合的交集:已属于A且属于B的元素称为A与B的交(集)
    	SINTER A B
    	
    	获取集合的并集:已属于 A 或属于 B 的元素为称为 A 与 B 的并(集)
    	 SUNION A B
    
    sorted set(有序集合): Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个 double(双精度浮点型)类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复,集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1),集合中最大的成员数为2^32-1(4294967295, 每个集合可存储 40 多亿个成员)。
    
    	生成有序集合
    	ZADD zset1 1 v1
    	ZADD zset1 2 v2
    	排行案例:
    	ZADD paihangbang 10 key1 20 key2 30 key3
    	ZREVRANGE paihangbang 0 -1 withscores #显示指定集合内所有 key 和得分情况
    	
    	批量添加多个数值
    	ZADD zset1 1 v1 2 v2 4 v3 5 v5
    	
    	获取集合的长度数
    	ZCARD zset1
    	ZCARD zset2
    	
    	基于索引返回数值
    	ZRANGE zset1 1 3
    	ZRANGE zset1 0 2
    	
    	返回某个数值的索引
    	ZRANK zset1 v2
    	
    哈希(hash):hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,Redis中每个hash可以存储2^32 - 1键值对(40 多亿)。
    	生成 hash key
    	HSET hset1 name tom age 18
    	
    	获取hash key字段值
    	HGET hset1 name
    	HGET hset1 age
    	
    	删除一个hash key的字段
    	HDEL hset1 name
    	
    	获取所有hash表中的字段
    	HKEYS hset1
    	
    	
    

    redis其它命令

    CONFIG

    config 命令用于查看当前 redis 配置、以及不重启更改 redis 配置等

    更改最大内存

    127.0.0.1:6379> CONFIG GET maxmemory  默认0无限制
    1) "maxmemory"
    2) "0"
    
    127.0.0.1:6379> CONFIG SET maxmemory 8589934592
    OK
    127.0.0.1:6379> CONFIG GET maxmemory
    1) "maxmemory"
    2) "8589934592"
    

    设置密码

    127.0.0.1:6379>  CONFIG SET requirepass 123456
    OK
    127.0.0.1:6379>  CONFIG GET requirepass  立即生效
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> AUTH 123456
    OK
    127.0.0.1:6379>  CONFIG GET requirepass 
    1) "requirepass"
    2) "123456"
    

    当前所有配置

    CONFIG GET *
    

    info

    显示当前节点 redis 运行状态信息

    SELECT

    切换数据库

    SELECT 1
    

    KEYS

    查看当前库下的所有 key

    KEYS *
    

    BGSAVE

    手动在后台执行 RDB 持久化操作

    DBSIZE

    返回当前库下的所有 key 数量

    FLUSHDB

    强制清空当前库中的所有 key

    FLUSHALL

    强制清空当前 redis 服务器所有数据库中的所有 key,即删除所有数据

    redis 配置文件

    bind 0.0.0.0 #监听地址,可以用空格隔开后多个监听 IP

    protected-mode yes #redis3.2 之后加入的新特性,在没有设置 bind IP 和密码的时候只允许访问127.0.0.1:6379

    port 6379 #监听端口

    tcp-backlog 511 #三次握手的时候 server 端收到 client ack 确认号之后的队列值。

    timeout 0 #客户端和 Redis 服务端的连接超时时间,默认是 0,表示永不超时。

    tcp-keepalive 300 #tcp 会话保持时间

    daemonize no #默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成yes,当 redis 作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面

    supervised no #和操作系统相关参数,可以设置通过 upstart 和 systemd 管理 Redis 守护进程,centos 7以后都使用 systemd

    pidfile /var/run/redis_6379.pid #pid 文件路径

    loglevel notice #日志级别

    logfile "" #日志路径

    databases 16 #设置 db 库数量,默认 16 个库

    always-show-logo yes #在启动 redis 时是否显示 log

    save 900 1 #在 900 秒内有一个键内容发生更改就出就快照机制

    save 300 10

    save 60 10000

    stop-writes-on-bgsave-error no #快照出错时是否禁止 redis 写入操作

    rdbcompression yes #持久化到 RDB 文件时,是否压缩,"yes"为压缩,"no"则反之

    rdbchecksum yes #是否开启 RC64 校验,默认是开启

    dbfilename dump.rdb #RDB模式快照文件名

    dir ./ #快照文件保存路径

    replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:

    ​ 1、如果replica-serve-stale-data 设置为 yes(默认设置),从库会继续响应客户端的读请求。

    ​ 2、如果replica-serve-stale-data 设置为 no,除去指定的命令之外的任何请求都会返回一个错误"SYNC with master inprogress"。

    replica-read-only yes #是否设置从库只读

    repl-diskless-sync no #是否使用 socket 方式复制数据,目前 redis 复制提供两种方式,disk 和 socket,如果新的 slave 连上来或者重连的 slave 无法部分同步,就会执行全量同步,master 会生成 rdb 文件,有 2 种方式:

    ​ disk 方式是 master 创建一个新的进程把 rdb 文件保存到磁盘,再把磁盘上的 rdb 文件传递给 slave,socket 是 master 创建一个新的进程,直接把 rdb 文件以 socket 的方式发给 slave,disk 方式的时候,当一个 rdb 保存的过程中,多个 slave 都能共享这个 rdb 文件,socket 的方式就是一个个 slave顺序复制,只有在磁盘速度缓慢但是网络相对较快的情况下才使用 socket 方式,否则使用默认的disk方式

    repl-diskless-sync-delay 30 #diskless 复制的延迟时间,设置 0 为关闭,一旦复制开始还没有结束之前master节点不会再接收新 slave 的复制请求,直到下一次开始

    repl-ping-slave-period 10 #slave 根据 master 指定的时间进行周期性的 PING 监测

    repl-timeout 60 #复制链接超时时间,需要大于 repl-ping-slave-period,否则会经常报超时

    repl-disable-tcp-nodelay no #在 socket 模式下是否在 slave 套接字发送 SYNC 之后禁用 TCP_NODELAY,如果你选择“yes”Redis 将使用更少的 TCP 包和带宽来向 slaves 发送数据。但是这将使数据传输到 slave上有延迟,Linux 内核的默认配置会达到 40 毫秒,如果你选择了 "no" 数据传输到 salve 的延迟将会减少但要使用更多的带宽

    repl-backlog-size 1mb #复制缓冲区大小,只有在 slave 连接之后才分配内存。

    repl-backlog-ttl 3600 #多次时间 master 没有 slave 连接,就清空 backlog 缓冲区。

    replica-priority 100 #当 master 不可用,Sentinel 会根据 slave 的优先级选举一个 master。最低的优先级的 slave,当选 master。而配置成 0,永远不会被选举。requirepass foobared #设置 redis 连接密码

    rename-command #重命名一些高危命令

    maxclients 10000 #最大连接客户端

    maxmemory #最大内存,单位为 bytes 字节,8G 内存的计算方式 8(G)1024(MB)1024(KB)*1024(Kbyte),需要注意的是 slave 的输出缓冲区是不计算在 maxmemory 内。

    appendonly no #是否开启 AOF 日志记录,默认 redis 使用的是 rdb 方式持久化,这种方式在许多应用中已经足够用了。但是 redis 如果中途宕机,会导致可能有几分钟的数据丢失,根据 save 来策略进行持久化,Append Only File 是另一种持久化方式,可以提供更好的持久化特性。Redis 会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时 Redis 都会先把这个文件的数据读入内存里,先忽略 RDB 文件。

    appendfilename "appendonly.aof" #AOF 文件名

    appendfsync everysec #aof 持久化策略的配置,no 表示不执行 fsync,由操作系统保证数据同步到磁盘,always 表示每次写入都执行 fsync,以保证数据同步到磁盘,everysec 表示每秒执行一次 fsync,可能会导致丢失这 1s 数据。

    appendfsync always # 每一个命令,都立即同步到aof

    appendfsync no # 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入磁盘

    no-appendfsync-on-rewrite no #在 aof rewrite 期间,是否对 aof 新记录的 append 暂缓使用文件同步策略,主要考虑磁盘 IO 开支和请求阻塞时间。默认为 no,表示"不暂缓",新的 aof 记录仍然会被立即同步,Linux 的默认 fsync 策略是 30 秒,如果为 yes 可能丢失 30 秒数据,但由于 yes 性能较好而且会避免出现阻塞因此比较推荐。

    auto-aof-rewrite-percentage 100 # 当 Aof log 增长超过指定百分比例时,重写 log file, 设置为 0 表示不自动重写 Aof 日志,重写是为了使 aof 体积保持最小,而确保保存最完整的数据。

    auto-aof-rewrite-min-size 64mb #触发 aof rewrite 的最小文件大小

    aof-load-truncated yes #是否加载由于其他原因导致的末尾异常的 AOF 文件(主进程被 kill/断电等)

    aof-use-rdb-preamble yes #redis4.0新增 RDB-AOF 混合持久化格式,在开启了这个功能之后,AOF 重写产生的文件将同时包含 RDB 格式的内容和 AOF 格式的内容,其中 RDB 格式的内容用于记录已有的数据,而 AOF 格式的内存则用于记录最近发生了变化的数据,这样 Redis 就可以同时兼有 RDB 持久化和AOF 持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据)。

    lua-time-limit 5000 #lua 脚本的最大执行时间,单位为毫秒

    cluster-enabled yes #是否开启集群模式,默认是单机模式

    cluster-config-file nodes-6379.conf #由 node 节点自动生成的集群配置文件

    cluster-node-timeout 15000 #集群中 node 节点连接超时时间

    cluster-replica-validity-factor 10 #在执行故障转移的时候可能有些节点和 master 断开一段时间数据比较旧,这些节点就不适用于选举为 master,超过这个时间的就不会被进行故障转移

    cluster-migration-barrier 1 #一个主节点拥有的至少正常工作的从节点,即如果主节点的 slave 节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。

    cluster-require-full-coverage no #集群槽位覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么 yes 情况下 redis 集群槽位验证不全就不再对外提供服务,而 no 则可以继续使用但是会出现查询数据查不到的情况(因为有数据丢失)。

    Slow log 是 Redis 用来记录查询执行时间的日志系统,slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。

    slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。

    slowlog-max-len 128 #记录多少条慢日志保存在队列,超出后会删除最早的,以此滚动删除

    127.0.0.1:6379> slowlog len

    (integer) 14

    127.0.0.1:6379> slowlog get

      1. (integer) 14
    1. (integer) 1544690617

    2. (integer) 4

      1. "slowlog"

    127.0.0.1:6379> SLOWLOG reset

    OK

    常见问题

    1、没有满足bgsave条件,shutdown会丢数据吗?

    不会,正常退出流程都会持久化保存dump.rdb文件

    pkill、kill、kill -15、shutdown都是正常退出流程,优雅关闭

    kill -9会丢失数据,不是正常退出流程

    每天进步一点点
  • 相关阅读:
    cgroup中对cpu资源控制的方式
    kube-proxy 原理
    k8s集群优化
    k8s集群从一千节点增加到五千台节点遇到的瓶颈
    k8s的service和ep是如何关联和相互影响的
    一个经典pod完整生命周期
    k8s中的pod内几个容器之间的关系是什么
    kubernetes包含几个组件。各个组件的功能是什么。组件之间是如何交互的。
    k8s的pause容器有什么用?是否可以去掉?
    强制删除pod,namespace等
  • 原文地址:https://www.cnblogs.com/Otiger/p/14580916.html
Copyright © 2011-2022 走看看