• Redis 入门-redis.conf详解


    Redis入门

    redis 是什么

    Redis(Remote Dictionary Server ),即远程字典服务

    是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

    • 内存存储。持久化、内存中断电即失、所以持久化很重要(rdb/aof)

    • 效率高,可用于高速缓存

    • 发布订阅系统

    • 地图信息分析等等

    持久化、集群 、事务、

    官网:https://redis.io/ 中文网:http://www.redis.cn/

    通过官网下载即可。

     

    Linux安装

    Windows安装下载解压双击即可。下载地址:GitHub

    #下载安装包,上传到opt目录下、并解压
    [root@localhost jdk1.8.0_261]# wget http://download.redis.io/releases/redis-6.0.8.tar.gz
    [root@localhost home]# mv redis-6.0.8.tar.gz /opt/
    [root@localhost opt]# tar zxvf redis-6.0.8.tar.gz
    [root@localhost opt]# ls
    redis-6.0.8 redis-6.0.8.tar.gz

    #进入解压的文件,可以看到redis的配置文件redis.conf
    #安装基本环境gcc-c++
    [root@localhost redis-6.0.8]# yum -y install gcc-c++
    [root@localhost redis-6.0.8]#make
      INSTALL redis-check-rdb
      INSTALL redis-check-aof
    Hint: It's a good idea to run 'make test' ;)
    make[1]: Leaving directory `/opt/redis-6.0.8/src' 代表make成功
    [root@localhost redis-6.0.8]#make install
    Hint: It's a good idea to run 'make test' ;)
      INSTALL install
      INSTALL install
      INSTALL install
      INSTALL install
      INSTALL install
    make[1]: Leaving directory `/opt/redis-6.0.8/src'   代表install成功
    #注意报错!make[1]: *** [server.o] Error 1
    #原因是因为gcc版本过低,yum安装的gcc是4.8.5的。因此需要升级gcc,升级过程如下:
    yum -y install centos-release-scl
    yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
    scl enable devtoolset-9 bash
    #修改环境变量
    echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile
    gcc -v
    make 和make install以后即可。
    #注意安装完成以后redis-server在/usr/local/bin/目录下。
    [root@localhost bin]# pwd
    /usr/local/bin
    [root@localhost bin]# ls
    redis-benchmark redis-check-rdb redis-sentinel
    redis-check-aof redis-cli       redis-server
    #拷贝/opt/redis-6.0.8/redis.conf文件到/usr/local/bin目录下
    [root@localhost bin]# cp /opt/redis-6.0.8/redis.conf .
    [root@localhost bin]# ls
    redis-benchmark redis-check-rdb redis.conf     redis-server
    redis-check-aof redis-cli       redis-sentinel
    #redis默认是前台启动的,修改配置文件
    vim redis.conf
    daemonize no 改为 daemonize yes 后台方式启动
    #启动redis服务、指定启动配置文件为redis.conf
    [root@localhost bin]# redis-server redis.conf
    [root@localhost bin]# ./redis-server ./redis.conf
    #客户端redis-cli连接测试:
    [root@localhost bin]# redis-cli -h localhost -p 6379 //默认本地可以不加-h
    localhost:6379> ping
    PONG
    localhost:6379> set name koeb
    OK
    localhost:6379> get name
    "koeb"
    localhost:6379> keys *   #查看所有的key
    1) "name"
    #查看redis进程是否开启
    [root@localhost redis-6.0.8]# ps -ef | grep redis
    root       7680      1  0 02:11 ?        00:00:00 redis-server 127.0.0.1:6379
    root       7688   2637  0 02:13 pts/0    00:00:00 redis-cli -h localhost -p 6379
    root       7713   7244  0 02:16 pts/1    00:00:00 grep --color=auto redis
    #关闭redis服务、并查看进程
    localhost:6379> shutdown
    not connected> exit
    [root@localhost redis-6.0.8]# ps -ef | grep redis
    root       7716   7244  0 02:17 pts/1    00:00:00 grep --color=auto redis

    会使用单机多redis启用

    测试性能

    redis-benchmark是一个压力测试时工具!

    Redis 自带了一个叫 redis-benchmark 的工具来模拟 N 个客户端同时发出 M 个请求。 (类似于 Apache ab 程序)。可以使用 redis-benchmark -h 来查看基准参数。

    测试:

    #100个并发连接  10w个请求
    -h 指定主机ip
    -p 指定端口
    -c 指定连接数
    -n 指定并发数
    [root@localhost bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000

     

    基础知识


    redis默认有16个数据库

    默认使用的是第0 个、可以使用select进行切换数据库!

    127.0.0.1:6379> SELECT 3  #切换数据库
    OK
    127.0.0.1:6379[3]> DBSIZE  #查看Db大小
    (integer) 0
    #
    127.0.0.1:6379[3]> set A qiang
    OK
    127.0.0.1:6379[3]> DBSIZE
    (integer) 1
    127.0.0.1:6379[3]> SELECT 7
    OK
    127.0.0.1:6379[7]> DBSIZE
    (integer) 0
    127.0.0.1:6379[7]> get A
    (nil)
    127.0.0.1:6379[7]> SELECT 3
    OK
    127.0.0.1:6379[3]> get A
    "qiang"
    #清空当前数据库:FLUSHDB 清空所有库:FLUSHALL
    127.0.0.1:6379[3]> keys *
    1) "A"
    127.0.0.1:6379[3]> FLUSHDB
    OK
    127.0.0.1:6379[3]> keys *
    (empty array)

    redis 是单线程的!

    redis是很快的,redis是基于内存操作,CPU不是redis性能瓶颈,redis的瓶颈是机的内存及网络带宽。

    redis为什么单线程这么快?C语言写的

    • 误区:高性能的服务器一定是多线程的、

    • 误区:多线程(cpu上下文切换)一定比单线程效率高、CPU>内存>硬盘

    核心:redis是将所有的数据全部放在内存中的,所以使用单线程去操作效率就是最高的、多线程(CPU上下文:耗时)。对于内存系统来说、单线程就是最佳的。

     

    5大基本数据类型


    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件MQ。 它支持多种类型的数据结构,如 字符串(strings)散列(hashes)列表(lists)集合(sets)有序集合(sorted sets) 与范围查询, bitmapshyperloglogs地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting)LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

    Redis-key

    127.0.0.1:6379> keys *  #查看所有key
    (empty array)
    127.0.0.1:6379> set name kobe  #设置 key
    OK
    127.0.0.1:6379> keys *
    1) "name"
    127.0.0.1:6379> set age 24
    OK
    127.0.0.1:6379> keys *
    1) "name"
    2) "age"
    127.0.0.1:6379> EXISTS name   #判断当前key是否存在
    (integer) 1
    127.0.0.1:6379> EXISTS name2
    (integer) 0
    127.0.0.1:6379> move name 1    #移除当前key
    (integer) 1
    127.0.0.1:6379> keys *
    1) "age"
    127.0.0.1:6379> set name kobe
    OK
    127.0.0.1:6379> keys *
    1) "name"
    2) "age"
    127.0.0.1:6379>
    127.0.0.1:6379> keys *
    1) "name"
    2) "age"
    127.0.0.1:6379> get name
    "kobe"
    127.0.0.1:6379> EXPIRE name 10   #设置key的过期时间 默认秒
    (integer) 1
    127.0.0.1:6379> ttl name         #查看当前key的剩余时间
    (integer) 3
    127.0.0.1:6379> ttl name
    (integer) 1
    127.0.0.1:6379> ttl name
    (integer) 1
    127.0.0.1:6379> ttl name
    (integer) 0
    127.0.0.1:6379> ttl name
    (integer) -2
    127.0.0.1:6379> set name kobe  
    OK
    127.0.0.1:6379> type name     #查看当前key的类型
    string
    127.0.0.1:6379> type age
    string

    官网命令文档:http://www.redis.cn/commands.html

     

    String(字符串)

    ------------------------------------------------------------
    127.0.0.1:6379> set key1 v1  #设置key
    OK
    127.0.0.1:6379> get key1     #获得key
    "v1"
    127.0.0.1:6379> keys *       #查看所有key
    1) "key1"
    127.0.0.1:6379> EXISTS key1  #判断key是否存在
    (integer) 1
    127.0.0.1:6379> APPEND key1 "hello"  #追加字符串,如果key不存在,就增加=set
    (integer) 7
    127.0.0.1:6379> get key1
    "v1hello"
    127.0.0.1:6379> STRLEN key1   #获取字符串长度
    (integer) 7
    127.0.0.1:6379> APPEND key1 "koebe"
    (integer) 12
    127.0.0.1:6379> get key1
    "v1hellokoebe"
    127.0.0.1:6379>
    ------------------------------------------------------------------
    127.0.0.1:6379> set views 0   #初始浏览量0
    OK
    127.0.0.1:6379> get views
    "0"
    127.0.0.1:6379> INCR views    #自增1
    (integer) 1
    127.0.0.1:6379> INCR views
    (integer) 2
    127.0.0.1:6379> DECR views   #自减1
    (integer) 1
    127.0.0.1:6379> DECR views
    (integer) 0
    127.0.0.1:6379> DECR views
    (integer) -1
    127.0.0.1:6379> DECR views
    (integer) -2
    127.0.0.1:6379> get views
    "-2"
    127.0.0.1:6379> INCRBY views 10  #设置步长、指定增量
    (integer) 8
    127.0.0.1:6379> INCRBY views 10
    (integer) 18
    127.0.0.1:6379> DECRBY views 5  #设置步长、指定减量
    (integer) 13
    127.0.0.1:6379> DECRBY views 5  
    (integer) 8
    ----------------------------------------------------------------
    #截取
    127.0.0.1:6379> set key1 hello
    OK
    127.0.0.1:6379> APPEND key1 ",lixingqiang"
    (integer) 17
    127.0.0.1:6379> get key1
    "hello,lixingqiang"
    127.0.0.1:6379> GETRANGE key1 0 4   #截取字符串 【0,4】
    "hello"
    127.0.0.1:6379> GETRANGE key1 0 -1 #截取字符串 【0,-1】 等于 get key1
    "hello,lixingqiang"
    ---------------------------------------------------------------------------
    #替换
    127.0.0.1:6379> set key2 abcdefg
    OK
    127.0.0.1:6379> get key2
    "abcdefg"
    127.0.0.1:6379> SETRANGE key2 1 XX  #替换指定位置开始的字符串:
    (integer) 7
    127.0.0.1:6379> get key2
    "aXXdefg"
    -----------------------------------------------------------------------------
    #setex (set with expire) #设置过期时间
    #setnx (set if not expire) #不存在再设置
    127.0.0.1:6379> setex key3 30 "hello"  #设置一个key3的值为hello 30秒后过期
    OK
    127.0.0.1:6379> ttl key3
    (integer) 24
    127.0.0.1:6379> get key3
    "hello"
    127.0.0.1:6379> setnx mykey "redis"  #如果mykey不存在,创建mykey
    (integer) 1
    127.0.0.1:6379> keys *
    1) "key1"
    2) "mykey"
    3) "key2"
    127.0.0.1:6379> ttl key3
    (integer) -2
    127.0.0.1:6379> setnx mykey "MongoDB"  #如果mykey存在,创建失败
    (integer) 0
    127.0.0.1:6379> get mykey
    "redis"
    -----------------------------------------------------------------------
    mset
    mget
    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #同事设置多个值
    OK
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    127.0.0.1:6379> mget k1 k2 k3   #同事获取多个值
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> msetnx k1 v1 k4 v4   #msetnx是一个原子性的操作,要么一起成功、否则全失败
    (integer) 0
    127.0.0.1:6379> get k4
    (nil)
    127.0.0.1:6379>

    127.0.0.1:6379> mset user:1:name zhangsan user:1:age 3
    OK
    127.0.0.1:6379> mget user:1:name user:1:age
    1) "zhangsan"
    2) "3"
    ---------------------------------------------------------------------
    #getset
    127.0.0.1:6379> getset db redis #如果不存在值,则返回nil、并设置值
    (nil)
    127.0.0.1:6379> get db
    "redis"
    127.0.0.1:6379> getset db mongodb  #如果存在值,获取原值、并设置新的值
    "redis"
    127.0.0.1:6379> get db
    "mongodb"

     

    list


    基本的数据类型,列表

    ------------------------------------------------
    127.0.0.1:6379> LPUSH list one   #将一个值或多个值,插入到列表的头部(左)
    (integer) 1
    127.0.0.1:6379> LPUSH list two
    (integer) 2
    127.0.0.1:6379> LPUSH list three
    (integer) 3
    127.0.0.1:6379> LRANGE list 0 -1  #获取list中值、可以获取区间值
    1) "three"
    2) "two"
    3) "one"
    127.0.0.1:6379> LRANGE list 0 1    
    1) "three"
    2) "two"
    127.0.0.1:6379> RPUSH list rigth   #将一个值或多个值,插入到列表的尾部(右)
    (integer) 4
    127.0.0.1:6379> LRANGE list 0 -1
    1) "three"
    2) "two"
    3) "one"
    4) "rigth"
    -------------------------------------------------------------------------
    lpop
    rpop
    127.0.0.1:6379> LRANGE list 0 -1
    1) "three"
    2) "two"
    3) "one"
    4) "rigth"
    127.0.0.1:6379> LPOP list    #移除列表list的第一个元素
    "three"
    127.0.0.1:6379> rPOP list    #移除列表list的最后一个元素
    "rigth"
    127.0.0.1:6379> LRANGE list 0 -1    
    1) "two"
    2) "one"
    ---------------------------------------------------------
    lindex
    127.0.0.1:6379> LRANGE list 0 -1
    1) "two"
    2) "one"
    127.0.0.1:6379> LINDEX list 1   #通过下标获取list中的某一值!
    "one"
    127.0.0.1:6379> LINDEX list 0
    "two"

    ----------------------------------------------------------------
    llen
    127.0.0.1:6379> FLUSHDB
    OK
    127.0.0.1:6379> LPUSH list one
    (integer) 1
    127.0.0.1:6379> LPUSH list two
    (integer) 2
    127.0.0.1:6379> LPUSH list three
    (integer) 3
    127.0.0.1:6379> LLEN list   # 返回列表的长度
    (integer) 3
    ----------------------------------------------------------------
    移除指定的值
    lrem
    127.0.0.1:6379> LRANGE list 0 -1
    1) "three"
    2) "three"
    3) "two"
    4) "one"
    127.0.0.1:6379> lrem list 1 one  #移除list集合中指定个数的value,精确匹配
    (integer) 1
    127.0.0.1:6379> LRANGE list 0 -1
    1) "three"
    2) "three"
    3) "two"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "three"
    2) "three"
    3) "two"
    127.0.0.1:6379> LREM list 2 three
    (integer) 2
    127.0.0.1:6379> LRANGE list 0 -1
    1) "two"
    ----------------------------------------------------------------
    trim修剪。
    127.0.0.1:6379> RPUSH mylist "hello"
    (integer) 1
    127.0.0.1:6379> RPUSH mylist "hello1"
    (integer) 2
    127.0.0.1:6379> RPUSH mylist "hello2"
    (integer) 3
    127.0.0.1:6379> RPUSH mylist "hello3"
    (integer) 4
    127.0.0.1:6379> LTRIM mylist 1 2   #通过下标截取指定的长度,保留指定的
    OK
    127.0.0.1:6379> LRANGE mylist 0 -1
    1) "hello1"
    2) "hello2"
    ----------------------------------------------------------------
    rpoplpush # 移除列表最后一个元素,并将它移动到新的列表中!
    127.0.0.1:6379> RPUSH list "hello"
    (integer) 1
    127.0.0.1:6379> RPUSH list "hello1"
    (integer) 2
    127.0.0.1:6379> RPUSH list "hello2"
    (integer) 3
    127.0.0.1:6379> RPOPLPUSH list otherlist # 移除列表最后一个元素,并将它移动到新的列表中!
    "hello2"
    127.0.0.1:6379> LRANGE list 0 -1  
    1) "hello"
    2) "hello1"
    127.0.0.1:6379> LRANGE otherlist 0 -1
    1) "hello2"
    ----------------------------------------------------------------
    lset #将列表中指定下标的值替换为另一个值,更新操作。
    127.0.0.1:6379> EXISTS list  # 判断这个列表是否存在
    (integer) 0
    127.0.0.1:6379> lset list 0 item    #如果不存在列表,去更新就会报错
    (error) ERR no such key
    127.0.0.1:6379> LPUSH list "value1"
    (integer) 1
    127.0.0.1:6379> LRANGE list 0  0
    1) "value1"
    127.0.0.1:6379> lset list 0 item   #如果存在、就更新当前下标的值
    OK
    127.0.0.1:6379> LRANGE list 0  0
    1) "item"
    127.0.0.1:6379> lset list 1 other   #如果不存在、则会报错
    (error) ERR index out of range
    -----------------------------------------------------------------------------
    linsert #将某个具体的value插入到列表中某个元素的前边或者后边
    127.0.0.1:6379> RPUSH list hello
    (integer) 1
    127.0.0.1:6379> RPUSH list world
    (integer) 2
    127.0.0.1:6379> LINSERT list before world other
    (integer) 3
    127.0.0.1:6379> LRANGE list  0 -1
    1) "hello"
    2) "other"
    3) "world"
    127.0.0.1:6379> LINSERT list after world wwww
    (integer) 4
    127.0.0.1:6379> LRANGE list  0 -1
    1) "hello"
    2) "other"
    3) "world"
    4) "wwww"

    实际上是个链表,

    • before Node after ,left ,right 都可以插入

    • 如果key不存在,创建新的链表。

    • 如果key存在,新增内容

    • 如果移除了所有值,空链表,也代表不存在!

    • 在两边插入或者改动值,效率最高、中间元素,相对效率会低一点~

    消息队列!(lpush rpop),栈(lpush lpop)

     

    set(集合)


    set中的值不能重复读的!

    Hash(哈希)


     

    三种特殊数据类型

    geospatial 地理位置

    hyperloglog

    bitmaps

     

    事务


    Redis事务本质:一组命令的集合!所有命令都会被序列化,在事务执行的过程中,会按照顺序执行!一次性、顺序性、排他性!执行一系列的命令!

    -----队列 set set set 执行 ----

    Redis事务没有隔离级别的概念!

    所有的命令在事务中,并没有直接被执行,只有发起命令的时候才会执行、exec

    Redis单条命令 是保证原子性的,但是事务不保证原子性!

    redis 的事务:

    • 开启事务()

    • 命令入队()

    • 执行事务()

    正常执行事务

     

    redis.conf详解


    启动的时候 就是通过配置文件启动的!

    单位:

    不区分大小写、对大小写不敏感

      9 # it in the usual form of 1k 5GB 4M and so forth:
     10 #
     11 # 1k => 1000 bytes
     12 # 1kb => 1024 bytes
     13 # 1m => 1000000 bytes
     14 # 1mb => 1024*1024 bytes
     15 # 1g => 1000000000 bytes
     16 # 1gb => 1024*1024*1024 bytes
     17 #
     18 # units are case insensitive so 1GB 1Gb 1gB are all the same.
    网络
      69 bind 127.0.0.1   #绑定ip
     88 protected-mode yes  #保护模式
     92 port 6379         #端口设置
    通用 general
      225 daemonize yes  #以守护进程方式运行、默认是no  需要开启yes
      247 pidfile /var/run/redis_6379.pid #如果以后台方式运行,就需要指定一个pid文件!
      日志:
      249 # Specify the server verbosity level.
      250 # This can be one of:
      251 # debug (a lot of information, useful for development/testing)
      252 # verbose (many rarely useful info, but not a mess like the debug lev     el)
      253 # notice (moderately verbose, what you want in production probably)
      254 # warning (only very important / critical messages are logged)
      255 loglevel notice
     
      260 logfile ""  # 日志的文件位置名
      275 databases 16  #数据库的数量 默认是16个
      283 always-show-logo yes   #是否显示logo
    快照

    持久化,在规定时间内,执行了多少次操作,则会持久化到文件(.rdb、.aof) redis 是内存数据库,如果没有持久化,那么数据断电即失!

      307 save 900 1   #如果900秒内,有1个key进行修改,就进行持久化操作
     308 save 300 10  #如果300秒内,有10个key进行修改,就进行持久化操作
     309 save 60 10000 #如果60秒内,有10000个key进行修改,就进行持久化操作
     #以后自己可以定义
     324 stop-writes-on-bgsave-error yes #持久化出错,是否继续工作
     330 rdbcompression yes #是否压缩rdb文件、需要消耗一些CPU资源。
     339 rdbchecksum yes  #保存rdb文件时,进行错误检测校验
     365 dir ./   #rdb文件保存的目录
    安全:

    redis默认是没有密码的 可以设置密码

    667 ################################## SECURITY #############################  
       127.0.0.1:6379> CONFIG GET requirepass   #获取密码
       1) "requirepass"
       2) ""
       127.0.0.1:6379> CONFIG sET requirepass 123456  # 设置密码
      OK
    [root@localhost bin]# redis-cli -p 6379
    127.0.0.1:6379> ping
    (error) NOAUTH Authentication required.
       127.0.0.1:6379> auth 123456   # 密码登录
    OK
    127.0.0.1:6379> ping
    PONG
    客户端限制
    ############################## CLIENTS  #################################
       833 # maxclients 10000 #设置客户端最大连接数
       860 # maxmemory <bytes> #redis配置最大的内存容量
       891 # maxmemory-policy noeviction   #内存满了后的处理策略:
      1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
        2、allkeys-lru : 删除lru算法的key  
            3、volatile-random:随机删除即将过期key  
        4、allkeys-random:随机删除  
        5、volatile-ttl : 删除即将过期的  
            6、noeviction : 永不过期,返回错误
    aof 配置
    #aof配置
    1069 ############################## APPEND ONLY MODE ########################
       1089 appendonly no  #默认是不开启aof模式的、默认使用rdb方式持久化的,在大部分情况下、rdb完全够用了。
       1093 appendfilename "appendonly.aof"  #持久化文件的名字  
       1119 appendfsync everysec  #每秒执行一次sync,可能会丢失这1秒的数据!
          appendfsync always     #每次修改都会写入sync,消耗性能
          appendfsync no         #不执行 sync,这个时候系统自己同步数据,速度最快!

     

  • 相关阅读:
    HTML 块级、内联、内联块级元素(转)
    CSS margin-top父元素下落
    JS 窗口resize避免触发多次
    ASP.NET 自制免费.NET代码生成器KevinCodeBuilder
    Plugin 中国省市选择插件
    Git 常用命令(转)
    JS Regex正则表达式的使用(转)
    Git 详细中文安装教程(转)
    业务逻辑中的测试总结(一)----比值类需求测试分解
    python学习笔记系列----(四)模块
  • 原文地址:https://www.cnblogs.com/james-23/p/13686761.html
Copyright © 2020-2023  润新知