设为首页 收藏本站
查看: 1119|回复: 0

[经验分享] 一步一步学习redis3.2.8

[复制链接]

尚未签到

发表于 2018-11-4 07:59:35 | 显示全部楼层 |阅读模式
  一步一步学习redis3.2.8
  1、redis安装
  官网地址为:https://redis.io/download
  $ wget http://download.redis.io/releases/redis-3.2.8.tar.gz
  $ tar xzf redis-3.2.8.tar.gz
  $ cd redis-3.2.8
  $ make
  启动服务
  $ src/redis-server
  redis-server /root/soft/redis/sbin/redis.conf &
  查看进程
  ps -ef | grep 6379
  交互式命令
  $ src/redis-cli
  redis> set foo bar
  OK
  redis> get foo
  "bar"
  bgsave  命令持久化数据到磁盘
  或者

  [root@node1 redis]# redis-cli set>  OK

  [root@node1 redis]# redis-cli get>  "1"
  redis-cli  -h 192.168.175.29 -p 6379
  2、redis.conf配置文件
  #bind 127.0.0.1
  关闭保护模式 远程可以连接
  protected-mode no
  port 6379
  日志隔离级别
  loglevel notice
  #log文件名称
  logfile "mylog.txt"
  默认数据库个数
  databases 16
  #   In the example below the behaviour will be to save:
  #   after 900 sec (15 min) if at least 1 key changed
  #   after 300 sec (5 min) if at least 10 keys changed
  #   after 60 sec if at least 10000 keys changed
  快照
  save 900 1
  save 300 10
  save 60 10000
  #DB文件名字
  # The filename where to dump the DB
  dbfilename dump.rdb
  #目录
  # Note that you must specify a directory here, not a file name.
  dir /root/soft/redis/sbin/db
  3、String 结构
  Java String
  C#   String   => char[]的封装。。。
  Redis C语言实现  char[] 进行了封装。。。   append,length,substring,set,
  get。。。。setrange => replace...
  二: 最常用命令。。。
  官网学习地址 http://www.redis.cn/documentation.html  翻译比较全,比较新
  《1》 set/get 命令    [对string进行赋值]  时间复杂度:O(1)
  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  GET key   【nil】 =>lua
  应用场景分布式锁。。。。【zookeeper】 相对来说重量级。
  通过对username的赋值的返回值来判断是否获取到了一个分布式锁。。。
  set username jack NX =》 如果返回ok,说明获得到了锁。。。
  set username mary NX =》 如果返回nil,说明没有获取到锁。。。
  《2》 Incr,Decr,    =>自增或者自减1     【 i++, i-- 】
  127.0.0.1:6379> set mykey "10"
  OK
  127.0.0.1:6379> object encoding mykey
  "int"
  127.0.0.1:6379>
  127.0.0.1:6379> incr mykey
  (integer) 11
  127.0.0.1:6379> get mykey
  "11"
  127.0.0.1:6379> get mykey
  "11"
  127.0.0.1:6379>
  127.0.0.1:6379> decr mykey
  (integer) 10
  127.0.0.1:6379> get mykey
  "10"
  IncrBy,DecrBy =>自增或者自减去指定的值 【 i=i + xx,  i=i - xx 】
  127.0.0.1:6379> get mykey
  "10"
  127.0.0.1:6379> incrby mykey 6
  (integer) 16
  127.0.0.1:6379> get mykey
  "16"
  127.0.0.1:6379> get mykey
  "16"
  127.0.0.1:6379> decrby mykey 9
  (integer) 7
  127.0.0.1:6379> get mykey
  "7"
  127.0.0.1:6379>
  Redis中的String不是string类型。。。   如果存放到string中的value是int,那么其实在内
  部还是用int的。。。
  从encoding可以看出。。。
  RedisObject中有一个type属性,
  有一个encoding属性。。。
  有一个ptr属性。 => SDS
  查看类型 OBJECT ENCODING
  127.0.0.1:6379> object encoding username
  "embstr"
  127.0.0.1:6379> set mykey "10"
  OK
  127.0.0.1:6379> object encoding mykey
  "int"
  从一个简单的String类型中,我们发现有int,embstr.... 【性能优化】
  三、String过期操作
  一:String 过期操作  一些 工具函数
  Redis  单线程的内存字典服务器。。。 过期时间  =》 [mamcache]  kv结构。
  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  缓存,和memcache做一样的功能。。。
  ttl username 用于查看当前还剩多少秒。。。 NativeCache
  EX seconds – Set the specified expire time, in seconds.
  PX milliseconds – Set the specified expire time, in milliseconds.
  NX – Only set the key if it does not already exist.
  XX – Only set the key if it already exist.
  EX seconds – 设置键key的过期时间,单位时秒
  PX milliseconds – 设置键key的过期时间,单位时毫秒
  NX – 只有键key不存在的时候才会设置key的值
  XX – 只有键key存在的时候才会设置key的值
  设置一个key mykey1值为"hello" 过期时间为5s
  127.0.0.1:6379> set mykey1 "hello" ex 5
  OK
  127.0.0.1:6379> get mykey1
  "hello"
  查看用于查看当前还剩多少秒
  127.0.0.1:6379> set mykey1 "hello" ex 5
  OK
  127.0.0.1:6379> ttl mykey1
  (integer) 4
  PSETEX key milliseconds value  《=》 Set key value [PX milliseconds]
  PSETEX和SETEX一样,唯一的区别是到期时间以毫秒为单位,而不是秒
  127.0.0.1:6379> PSETEX mykey 10000 "Hello"
  OK
  127.0.0.1:6379> get mykey
  "Hello"
  127.0.0.1:6379> pttl mykey
  (integer) 2189
  SETEX key seconds value   《=》   Set key value [EX seconds]
  127.0.0.1:6379> setex mykey 10 "hello"
  OK
  127.0.0.1:6379> get mykey
  "hello"
  一样用法
  二:String
  1. len => StrLen   时间复杂度:O(1)
  返回key的string类型value的长度。如果key对应的非string类型,就返回错误
  127.0.0.1:6379> set mykey "abcdef"
  OK
  127.0.0.1:6379> get mykey
  "abcdef"
  127.0.0.1:6379> STRLEN mykey
  (integer) 6
  2. substring => GetRange   => getRange username 0 2
  时间复杂度:O(N) N是字符串长度,复杂度由最终返回长度决定,但由于通过一个字符串创建
  子字符串是很容易的,它可以被认为是O(1)。
  127.0.0.1:6379>  SET mykey "This is a string"
  OK
  127.0.0.1:6379> getrange mykey 0 3
  "This"
  127.0.0.1:6379>
  127.0.0.1:6379>
  127.0.0.1:6379> getrange mykey -3 -1
  "ing"
  127.0.0.1:6379> getrange mykey 0 -1
  "This is a string"
  127.0.0.1:6379> getrange mykey 10 100
  "string"
  127.0.0.1:6379>
  3. replace => SetRange 
  SETRANGE key offset value  =>
  127.0.0.1:6379> SET key1 "Hello World"
  OK
  127.0.0.1:6379> SETRANGE key1 6 "Redis"
  (integer) 11
  127.0.0.1:6379>
  127.0.0.1:6379> get key1
  "Hello Redis"
  127.0.0.1:6379> get username
  "jack"
  127.0.0.1:6379> setRange username 4 "12345"
  (integer) 9
  127.0.0.1:6379> get username
  "jack12345"
  Append命令
  127.0.0.1:6379> set mykey a
  OK
  127.0.0.1:6379> APPEND mykey bbbb
  (integer) 5
  127.0.0.1:6379> get amykey
  (nil)
  127.0.0.1:6379> get mykey
  "abbbb"
  exists判断一个key是否存在 1表示存在 0表示不存在
  127.0.0.1:6379> EXISTS mykey
  (integer) 1
  127.0.0.1:6379>
  127.0.0.1:6379>
  127.0.0.1:6379> get mykey
  "abbbb"
  127.0.0.1:6379> exists sss
  (integer) 0
  ###########非常重要############################################
  四、String 4
  一:位运算
  SDS => char[]   xxxx xxxx    char
  xxxx xxxx    char
  xxxx xxxx    char
  1. 百雀林:500w左右的用户  => customerid
  比如给某一批用户发送短信【营销】。。。 下午10点。。。  上午创建
  【交易金额大于50的,上海地区的,购买过某一个商品】
  customerid,customerid,cutomerid,customerid。
  table: customerid,customerid,cutomerid,customerid。  【300w】  Max:500w
  10,20,30,31,32,33,999,1222,......   【几百M】
  【customerid不重复】 我们customerid上限。
  SDS => char[]   0000 0000    char
  0100 0000    char
  0001 0000    char
  char[375000]                        => 几M就搞定了。。。
  C#: BitArray   [位数组]
  Redis位运算:
  SETBIT key offset value  =>   String的value大小是512M   【数据传输太慢了】 【多而小
  的数据】
  String的value大小是512M

  static int checkStringLength(client *c, long long>  if (size > 512*1024*1024) {

  addReplyError(c,"string exceeds maximum allowed>  return C_ERR;
  }
  return C_OK;
  }
  01234567
  char  => 从左到右   0000 0000   => offset = 7, set=1   => 0000 0001   => offset =
  6, set=1   => 0000 0011
  SDS => char[]   0000 0000    char
  0100 0000    char
  0001 0000    char
  。。。
  customerid:10,20,
  127.0.0.1:6379> SETBIT num 7 1
  (integer) 0
  127.0.0.1:6379> get num
  "\x01"
  127.0.0.1:6379> SETBIT num 6 1
  (integer) 0
  127.0.0.1:6379> get num
  "\x03"
  查看数量BITCOUNT
  127.0.0.1:6379> SETBIT num 10 1
  (integer) 0
  127.0.0.1:6379> SETBIT num 20 1
  (integer) 0
  127.0.0.1:6379> BITCOUNT num
  (integer) 4
  GETBIT key offset
  127.0.0.1:6379> GETBIT num 6
  (integer) 1
  127.0.0.1:6379> GETBIT num 7
  (integer) 1
  127.0.0.1:6379> GETBIT num 10
  (integer) 1
  127.0.0.1:6379> GETBIT num 5
  (integer) 0
  127.0.0.1:6379> GETBIT num 20
  (integer) 1
  BITCOUNT key [start end]  => 获取1的个数
  BITOP operation destkey key [key ...]  => AND OR XOR NOT  [JAVA,C#]
  对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
  0000  0001   => 1
  & 0000  0010   => 2
  --------------
  0000  0000   => 0
  1 & 2 = 0
  BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN ,对一个或多个 key 求逻辑并,
  并将结果保存到 destkey 。
  BITOP OR destkey srckey1 srckey2 srckey3 ... srckeyN,对一个或多个 key 求逻辑或,并
  将结果保存到 destkey 。
  BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN,对一个或多个 key 求逻辑异
  或,并将结果保存到 destkey 。
  BITOP NOT destkey srckey,对给定 key 求逻辑非,并将结果保存到 destkey
  127.0.0.1:6379> setbit num1 7 1
  (integer) 0
  127.0.0.1:6379> setbit num2 6 1
  (integer) 0
  127.0.0.1:6379> get num1
  "\x01"
  127.0.0.1:6379> get num2
  "\x02"
  127.0.0.1:6379> bitop and num3 num1 num2
  (integer) 1
  127.0.0.1:6379> get num3
  "\x00"
  127.0.0.1:6379>
  4、list双向结构
  一:List  JAVA,C# 【Array】形式来实现的。。。
  双向链表,[单链表,单向循环链表,双向。。。十字链表]
  [队列 和 栈]  queue,  stack
  二:从源代码中了解List是如何构造的。。。
  typedef struct listNode {
  struct listNode *prev;
  struct listNode *next;
  void *value;
  } listNode;
  //迭代一个中间变量
  typedef struct listIter {
  listNode *next;
  int direction;
  } listIter;
  typedef struct list {
  listNode *head;
  listNode *tail;
  void *(*dup)(void *ptr);
  void (*free)(void *ptr);
  int (*match)(void *ptr, void *key);
  unsigned long len;
  } list;
  为了方便对listNode进行管理,redis中使用list进行包装。。。
  len:统计当前双向链表中的listnode的个数。。。 O(1)
  list在redis中存放的形式:
  redisObject
  type:    (0,1,2,3,4)  1
  encoding:
  ptr
  ptr => string   sds
  prtr =>list      list -> listNode
  RedisDb => Dict => key: redisObject    value:redisObject
  ptr =>  list[双向链表]
  /* Object types */
  #define OBJ_STRING 0
  #define OBJ_LIST 1
  #define OBJ_SET 2
  #define OBJ_ZSET 3
  #define OBJ_HASH 4
  时间复杂度都是:O(1)
  LPUSH key value [value ...]  【redis做催付订单,卖家发货,签收提醒】
  LPOP key
  RPUSH key value [value ...]
  RPOP key
  LLEN key
  例子LPUSH:
  127.0.0.1:6379> LLEN mylist
  (integer) 0
  127.0.0.1:6379> lpush mylist "world"
  (integer) 1
  127.0.0.1:6379> LLEN mylist
  (integer) 1
  127.0.0.1:6379> lpush mylist "hello"
  (integer) 2
  127.0.0.1:6379> LLEN mylist
  (integer) 2
  127.0.0.1:6379> lrange mylist 0 -1
  1) "hello"
  2) "world"
  #####RPOP用法
  127.0.0.1:6379> lpush order "1001"
  (integer) 1
  127.0.0.1:6379> lpush order "1002"
  (integer) 2
  127.0.0.1:6379> lpush order "1003"
  (integer) 3
  127.0.0.1:6379> LRANGE order 0 -1
  1) "1003"
  2) "1002"
  3) "1001"
  127.0.0.1:6379> rpop order
  "1001"
  127.0.0.1:6379> LRANGE order 0 -1
  1) "1003"
  2) "1002"
  127.0.0.1:6379>
  client     redis:list      server
  orderid:  1001
  orderid:  1002
  orderid:  1003
  一:list 阻塞版本
  client  ->   list    -> server
  while(true){
  try{
  var info= list.Rpop();
  ....process....
  }
  catch{
  }
  finally{
  Thread.Sleep(1000);
  }
  }
  没有数据的情况下,我们还是一直的轮询redis。。。
  while(true){
  try{
  var info= list.BRpop();   => 阻塞
  ....process....
  }
  catch{
  }
  finally{
  Thread.Sleep(1000);
  }
  }
  BRpop,BLpop  两种方式
  BRPOP key [key ...] timeout 【s为单位】
  timeout: 0 表示永远等待 【connection被阻塞】
  timeout:10 表示10s过期
  MSMQ,RabbitMQ 都有这种等待。。。
  例子:
  127.0.0.1:6379> rpush orders 1001
  (integer) 1
  127.0.0.1:6379> rpush orders 1002
  (integer) 2
  127.0.0.1:6379> rpush orders 1003
  (integer) 3
  127.0.0.1:6379> rpush orders 1004
  (integer) 4
  127.0.0.1:6379> rpush orders 1005
  (integer) 5
  现象
  127.0.0.1:6379> BRPOP orders 0
  1) "orders"
  2) "1004"
  127.0.0.1:6379> BRPOP orders 0
  1) "orders"
  2) "1003"
  127.0.0.1:6379> BRPOP orders 0
  1) "orders"
  2) "1002"
  127.0.0.1:6379> BRPOP orders 0
  1) "orders"
  2) "1001"
  127.0.0.1:6379> BRPOP orders 0
  .......
  这里在等待,阻塞
  因为 BRPOP 和 BLPOP 基本是完全一样的,除了它们一个是从尾部弹出元素,而另一个是从头
  部弹出元素。
  将当前的key和 timeout给了client struct。。。
  c->bpop.timeout = timeout;
  c->bpop.target = target;
  在生产环境中使用的比较多的。。。
  二:工具函数
  LINDEX key index  获取index位置的数组。。。O(N)
  if (quicklistIndex(o->ptr, index, &entry))
  head -> tail 进行遍历
  127.0.0.1:6379> lindex orders 2
  "10001"
  127.0.0.1:6379> lrange orders 0 5
  1) "10007"
  2) "10008"
  3) "10001"
  4) "10002"
  5) "10003"
  127.0.0.1:6379>
  LRANGE key start stop   O(N+M)
  LINDEX用法:(生产环境少用,因为数据不断变化)
  127.0.0.1:6379> lpush a 1
  (integer) 1
  127.0.0.1:6379> lpush a 2
  (integer) 2
  127.0.0.1:6379> lpush a 3
  (integer) 3
  127.0.0.1:6379> lpush a 4
  (integer) 4
  127.0.0.1:6379> LINDEX a 0
  "4"
  127.0.0.1:6379> LINDEX a -1
  "1"
  start: 可以是+,-
  stop :结束
  js: substr
  LRANGE key start stop  O(N)
  redis> RPUSH mylist "one"
  (integer) 1
  redis> RPUSH mylist "two"
  (integer) 2
  redis> RPUSH mylist "three"
  (integer) 3
  redis> LRANGE mylist 0 0
  1) "one"
  redis> LRANGE mylist -3 2
  1) "one"
  2) "two"
  3) "three"
  LINSERT key BEFORE|AFTER pivot value
  value插入到pivot之前还是之后。。。
  LSET key index value   => 找index需要时间的。。。
  5、hash结构
  1. 催付规则    [商品价格>30 ,上海地区的,不是黑名单用户,购买过某个商品]
  符合就发催付。。。
  联合利华:
  施华蔻:
  都市大药房旗舰店: 【商品维度】
  hash:

  shopid    regularID  regularEntity  >
  regularID  regularEntity  >  trade:  hgetall  获取所有的hash表内容 【共享内存】  ,避免每次来trade都要读取mysql
  2. 分库分表:【shopid 都有一个DB】
  hash:
  shopalloc
  shopid   dbconnection
  shopid   dbconnection
  3. 策略使用 【复杂均衡】   hget,hkeys,hvals
  logicserver
  client  ->  sellernick    ->   router         logicserver
  logicserver
  hash:  routeralloc
  sellernick logicserverIP
  sellernick logicserverIP
  Monitor => 用于给指定的sellernick分配logicserver
  db中的sellernickList 和 redis中的sellernickList进行比较。。。。
  从redis中一次性把所有的sellernick捞出来,,, hkeys
  HGETALL key  获取hash中的所有数据
  127.0.0.1:6379> hset shopid_1 regularID_1 entity
  (integer) 1
  127.0.0.1:6379> hset shopid_1 regularID_2 entity2
  (integer) 1
  127.0.0.1:6379> hset shopid_1 regularID_3 entity3
  (integer) 1
  127.0.0.1:6379> hgetAll shopid_1
  1) "regularID_1"
  2) "entity"
  3) "regularID_2"
  4) "entity2"
  5) "regularID_3"
  6) "entity3"
  127.0.0.1:6379>
  例子:
  127.0.0.1:6379> hset persons username "jack"
  (integer) 1
  127.0.0.1:6379> hset persons password "123456"
  (integer) 1
  127.0.0.1:6379> hget persons username
  "jack"
  127.0.0.1:6379> hget persons password
  "123456"
  127.0.0.1:6379> HGETALL persons
  1) "username"
  2) "jack"
  3) "password"
  4) "123456"
  4. 短信通道
  sellernick  channel1
  sellernick  channel2
  HDEL key field [field ...]    用于删除hash表。。。
  HEXISTS key field             O(1)
  hash:用于定值查找,时间复杂度永远都是O(1)   => hashfunction
  127.0.0.1:6379> hset shopalloc 1 www.baidu.com
  (integer) 1
  127.0.0.1:6379> hset shopalloc 2 www.google.com
  (integer) 1
  127.0.0.1:6379> hlen shopalloc
  (integer) 2
  127.0.0.1:6379> hexists shopalloc 1
  (integer) 1
  127.0.0.1:6379> hexists shopalloc 1
  (integer) 1
  127.0.0.1:6379> hexists shopalloc 2
  (integer) 1
  127.0.0.1:6379> hexists shopalloc 3
  (integer) 0
  127.0.0.1:6379> hexists shopalloc 3
  HINCRBY key field increment
  对field中的value进行递增,递增的值就是increment。。。。    String: incr
  HKEYS key 所有hashtable中的所有keys。。。
  127.0.0.1:6379> hkeys shopalloc
  1) "1"
  2) "2"
  127.0.0.1:6379> hvals shopalloc
  1) "www.baidu.com"
  2) "www.google.com"
  HLEN key
  HMSET key field value [field value ...]  批量的执行mset。。。 通过一次tcp操作全部塞
  入到key中。。。
  HSETNX key field value 【NX】 =>  【Not Exists】   做分布式锁【轻量级】
  HSTRLEN key field 获取field中的value的长度
  127.0.0.1:6379> hstrlen shopalloc 1
  (integer) 13
  127.0.0.1:6379> hstrlen shopalloc 2
  (integer) 14
  6、set结构
  一:Set
  Set => 没有value的Hash
  hash
  k, v
  Set  【空间要节省的多】
  k
  二:应用场景 用户画像
  ShopID: 旗舰店下面
  Trade
  商品维度:
  productid_1: customerid,customerid ...........    Set
  productid_2: customerid,customerid .......         Set
  交易维度
  customerid_1: 总交易金额,平均交易金额
  地区维度:
  shanghai: customerid,customerid..... Set
  beijing:  customerid,customerid.... Set
  购买 “洗发水” 上海地区的。。。     【关联推荐】
  “洗发水”的productid:   看一下集合中是否有命中该customerid  O(1)
  “上海” areaid:     看一下集合中是否包含。。。
  如果两项都命中,那么我们直接发送“推荐”的彩信和邮件。。。。h5。
  1. query,我们基本上做到了O(1)  cluster集群
  2. maintain 维护
  二:常见命令
  1. SADD
  SADD key member [member ...]     单个或者批量添加,节省的是我们tcp的传输量。。。
  2. SISMEMBER
  SISMEMBER key member   用于判断制定的member是否是set中的成员。。。
  旗舰店基本上商品数都在1w之内。。。。 遍历1w次redis耗费的时候也就在5s内。。。。 【局
  域网】
  例子
  127.0.0.1:6379> sadd product_2 11 21 31 41
  (integer) 4
  127.0.0.1:6379> SMEMBERS product_2
  1) "11"
  2) "21"
  3) "31"
  4) "41"
  127.0.0.1:6379> SISMEMBER product_2 11
  (integer) 1
  127.0.0.1:6379>
  3.交集,差集,并集
  交集: SINTER key [key ...]   后面都是要比较的key
  并集: SUNION key [key ...]
  差集: SDIFF key [key ...]
  4. SCARD key  获取Set的元素个数
  5. SPOP key [count] 随机弹出一个元素并且移除。。
  Removes and returns one or more random elements from the set value store at key.
  6. SMEMBERS key  【查看所有的成员数据】
  共享内存,强大的redis set集合。。。
  7、sorted set 结构
  一:SortedSet   Java,C# 【SortDictinory 有序字典=> 红黑树(很复杂一种树结构,减少
  旋转)】
  redis:skiplist 【跳跃表】 90年   【链表 来达到树的一个效果】  AVL,RedBlackTree
  严格的Log2N复杂度。。。
  1. 如何更快的时间,经过更少的城市达到目标城市
  《1》到达北京: 直接飞机 一站达到  O(1)
  《2》天津:     四个节点到天津。
  【层次链表】 达到均摊的log2N 的时间复杂度。。。
  2. 添加数据到sortedset中。。。。
  《1》 优先级队列
  《2》 top10的操作 【top N 大根堆,小根堆】
  ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
  k:score      【权重,优先级】
  v:member
  127.0.0.1:6379> zadd trades 10 trade_10
  (integer) 1
  127.0.0.1:6379> zadd trades 20 trade_20
  (integer) 1
  127.0.0.1:6379> zadd trades 30 trade_30
  (integer) 1
  127.0.0.1:6379> zadd trades 40 trade_40
  (integer) 1
  127.0.0.1:6379> zadd trades 50 trade_50
  (integer) 1
  127.0.0.1:6379>
  1.如果获取所有的数据
  127.0.0.1:6379> zrange trades 0 -1    【从小到大的排序】
  1) "trade_10"
  2) "trade_20"
  3) "trade_30"
  4) "trade_40"
  5) "trade_50"
  127.0.0.1:6379>
  ###反向
  127.0.0.1:6379> zrevrange trades 0 -1
  1) "trade_50"
  2) "trade_40"
  3) "trade_30"
  4) "trade_20"
  5) "trade_10"
  127.0.0.1:6379> zrange trades 0 -1 withscores
  1) "trade_10"
  2) "10"
  3) "trade_20"
  4) "20"
  5) "trade_30"
  6) "30"
  7) "trade_40"
  8) "40"
  9) "trade_50"
  10) "50"
  127.0.0.1:6379>
  ZREVRANGE key start stop [WITHSCORES] 根据
  优先级队列:
  1. 先获取最大值:
  127.0.0.1:6379> zrevrange trades 0 0
  1) "trade_50"
  2. 删除最大值
  127.0.0.1:6379> zremrangebyrank trades -1 -1
  (integer) 1
  127.0.0.1:6379> zrevrange trades 0 -1
  1) "trade_50"
  2) "trade_40"
  3) "trade_30"
  4) "trade_20"
  5) "trade_10"
  127.0.0.1:6379> zrevrange trades 0 0
  1) "trade_50"
  127.0.0.1:6379> zremrangebyrank trades -1 -1
  (integer) 1
  127.0.0.1:6379> zrevrange trades 0 -1
  1) "trade_40"
  2) "trade_30"
  3) "trade_20"
  4) "trade_10"
  127.0.0.1:6379>
  一般来说做两次操作。。。 【redis】 做优先级队列面临的一些问题。。。
  Rabbitmq 专业级别的MQ产品。
  8、HyperLogLog
  一:hyperloglog  【算法】
  1. distinct + count
  我们计算某一台的独立ip。。。。
  《1》 使用set来保存某一天的所有ip数字。。。
  set  2016-12-26    192.168.10.121 192.168.10.122 192.168.10.123  192.168.10.121
  独立IP是多少呢?  3个。。。
  这时候,如果ip有1kw。。1ww。。。  【耗费巨大的内存】
  《2》 hyperloglog 需要解决这种问题。。。
  1. 节省内存 每个HyperLogLog结构需要12K字节再加上key本身的几个字节
  hyperloglog + len(key)   最多也就是几十k
  能够解决别人几百M所能解决的问题。。。
  hyperloglog不存储value,只是计算基数值。。。
  pfadd:   PFADD key element [element ...]
  pfcount: PFCOUNT key [key ...]
  pfmerge:
  2. 弊端:  有一定的错误率。。。   用错误率换取空间。。。  0.81% 。。。
  二:Sort 【一个排序】 对key进行操作的。。
  SORT key [BY pattern] [LIMIT offset count] [GET pattern] [ASC|DESC] [ALPHA]
  destination
  更适合的去模仿sql。。。
  如何让redis 模仿sql的一些语法
  1. 直接sort key
  sort uid
  127.0.0.1:6379> sort uid
  1) "1"
  2) "2"
  3) "3"
  127.0.0.1:6379> sort uid desc
  1) "3"
  2) "2"
  3) "1"
  127.0.0.1:6379>
  2. sort limit
  select uid from users limit 0 1 desc
  127.0.0.1:6379> sort uid limit 0 1 desc
  1) "3"
  127.0.0.1:6379> sort udi limit 0 1 asc
  (empty list or set)
  127.0.0.1:6379> sort uid limit 0 1 asc
  1) "1"
  3. sort [BY pattern]
  uid  username_{0}  age_{1}
  1    jack          30
  2    mary          15
  3    john          20
  select usename from users order by age desc
  jack
  john
  mary
  上面这种场景该如何实现???
  127.0.0.1:6379> sort uid by age_* get username_* desc
  1) "jack"
  2) "john"
  3) "mary"
  4. 我在获取usename的时候,想把uid也捞出来。。。
  select uid,username from users order by age desc。。。
  sort uid by age_* get username_* get #  desc
  5. 获取所有。。。
  select uid,username,age from users order by age desc....
  127.0.0.1:6379> sort uid by age_* get username_* get # get age_*  desc
  1) "jack"
  2) "1"
  3) "30"
  127.0.0.1:6379>  HMSET user_info_1 name admin level 9999
  OK
  127.0.0.1:6379> HMSET user_info_2 name jack level 10
  OK
  127.0.0.1:6379>  HMSET user_info_3 name peter level 25
  OK
  127.0.0.1:6379>  HMSET user_info_4 name mary level 70
  OK
  127.0.0.1:6379> sort uid
  1) "1"
  2) "2"
  3) "3"
  127.0.0.1:6379> rpush uid 4
  (integer) 4
  127.0.0.1:6379> sort uid
  1) "1"
  2) "2"
  3) "3"
  4) "4"
  127.0.0.1:6379> sort uid by user_info_*->level get user_info_*->name
  1) "jack"
  2) "peter"
  3) "mary"
  4) "admin"
  127.0.0.1:6379> sort uid by user_info_*->level get user_info_*->name  desc
  1) "admin"
  2) "mary"
  3) "peter"
  4) "jack"
  127.0.0.1:6379>
  4) "john"
  5) "3"
  6) "20"
  7) "mary"
  8) "2"
  9) "15"
  127.0.0.1:6379>
  复杂度不低的。。而且能不用就不用。。。毕竟以性能为代价。。。
  9、transaction事务
  一:transaction
  mysql,sqlserver。。。【复杂的机制】
  nosql:为了保持简洁性,或多或少的砍掉了一些transaction的一些特性。。。弱化。。。
   create
   commit
   rollback
  multi
  xxxxxxx
  exec 【提交】
  discard 【取消】
  watch,unwatch 【监测或者取消】
  127.0.0.1:6379> flushall
  OK
  127.0.0.1:6379> multi
  OK
  127.0.0.1:6379> set useranme jack
  QUEUED
  127.0.0.1:6379> set password 12345
  QUEUED
  127.0.0.1:6379> exec
  1) OK
  2) OK
  127.0.0.1:6379> keys *
  1) "password"
  2) "useranme"
  127.0.0.1:6379>
  127.0.0.1:6379> multi
  OK
  127.0.0.1:6379> set username jack
  QUEUED
  127.0.0.1:6379> set password 123456
  QUEUED
  127.0.0.1:6379> discard
  OK
  127.0.0.1:6379> keys *
  (empty list or set)
  127.0.0.1:6379>
  二:watch
  mysql,sqlserver。。
  watch num
  multi  【在事务执行的过程中,我不希望被别人修改】
  incr num   【0,1  ,2】  本来你想从0 -> 1  结果,看到的效果就是 0 -> 2 了。。。
  exec [discard]
  multi
  incr num
  exec  【取消】
  client incr num
  《1》不用watch
  incr :生成订单号。。。。   discard。。。
  watch的本意就是要保证在mutli的过程中,数据必须是干净的。。。。
  redisDb中有一个watched_keys
  10、pub与sub
  一:发布订阅模式
  1. 观察者模式 【设计模式中的一种】  .net  WPF 中就有一种MVVM模式。。
  js    knockoutjs mvvm模式。。。
  subject
  subscribe  subcribe  subcribe  subcribe
  SUBSCRIBE channel [channel ...]
  channel:就是subject 【频道】    收音机
  PUBLISH channel message   用于更新。。。
  ##发送端
  127.0.0.1:6379> PUBLISH 188.12 "hello"
  (integer) 1
  127.0.0.1:6379> PUBLISH new.* "hello"
  (integer) 1
  127.0.0.1:6379>
  ##接受端1
  127.0.0.1:6379> subscribe new.*
  Reading messages... (press Ctrl-C to quit)
  1) "subscribe"
  2) "new.*"
  3) (integer) 1
  1) "message"
  2) "new.*"
  3) "hello"
  ##接受端2
  127.0.0.1:6379> SUBSCRIBE 188.12
  Reading messages... (press Ctrl-C to quit)
  1) "subscribe"
  2) "188.12"
  3) (integer) 1
  1) "message"
  2) "188.12"
  3) "hello"
  直接订阅特定的频道,一对一的关系。。。
  如果订阅一个类别。。。 【模式匹配】  new.*   => new.it  or  new.sport
  *:正则字符
  PSUBSCRIBE pattern [pattern ...]  => p[pattern] 模式。。。
  MQ: Rabbitmq   【发布订阅模式】
  client ->  mq  ->  server     【长连接】
  [root@localhost Desktop]# redis-cli
  127.0.0.1:6379> subscribe 188.12
  Reading messages... (press Ctrl-C to quit)
  127.0.0.1:6379> psubscribe news.*
  Reading messages... (press Ctrl-C to quit)
  如果client端推送大量的消息,,, 1s  100
  这时候server并不能快速的处理,,,, logic process..... 而且读取db,soa webapi...
  这时候server不能及时处理,导致大量积压。。。 【1:memory挂掉。。。
  2:cpu 100%
  3:容易丢失消息[server挂掉]】
  二:源码 [RedisClient]
  1. 非模式       dict *pubsub_channels;  /* channels a client is interested in
  (SUBSCRIBE) */   字典
  key           value
  subject1        client1 -> client2  -> client3  ->
  client4
  subject2        client1 -> client9
  publish subject1 helloworld   所以查找key的复杂度是O(1)
  2. 模式         list *pubsub_patterns;  /* patterns a client is interested in
  (SUBSCRIBE) */   链表
  pubsubPattern   ->  pubsubPattern
  c1                  c3
  pattern= news.*    pattern= trip.*
  使用redis,定义的模式匹配的频道不会特别多。。。肯定不会超过100个。。。  遍历的复杂
  度O(N)
  11、过期键EXPIRE
  1. redis 作为Cache使用。。。
  set username jack  ....[ms] [ms]
  2.第一种,初始化设置。。。  set
  第二种:后期更改
  第三种:过期变成持久。。。
  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  1、EXPIRE key seconds  将一个key变为过期键。。。   【以s为单位】
  2、PEXPIRE key milliseconds  将一个key变成过期键, 【以ms为单位】
  3、以某一个时间点为过期键,比如说,2016-12-27 9:07   想 2016-12-27 10:00 过
  期。。。。
  EXPIREAT key timestamp
  127.0.0.1:6379> set a a
  OK
  127.0.0.1:6379> EXPIRE a 10
  (integer) 1
  127.0.0.1:6379> ttl a
  (integer) 7
  127.0.0.1:6379>
  127.0.0.1:6379>
  127.0.0.1:6379>
  127.0.0.1:6379> ttl a
  (integer) -2
  Cache
  redis作为一个Cache。。。   memcache 真的是一样的。。。
  # maxmemory    设置最大的内存  byte为单位。。。
  server:100M
  maxmemory: 50M
  如果数据大于50M我该怎么办???
  # volatile-lru -> remove the key with an expire set using an LRU algorithm
  # allkeys-lru -> remove any key according to the LRU algorithm
  # volatile-random -> remove a random key with an expire set
  # allkeys-random -> remove a random key, any key
  # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
  # noeviction -> don't expire at all, just return an error on write operations
  lru => leaset recently used  【最久未使用的】
  volatile-lru:  从过期键中去找最久未使用的数据。。。
  allkeys-lru:    从所有的keys中通过lru算法去删除。。。
  volatile-ttl:  redisObject  找到马上要过期的lru时间
  # maxmemory-policy noeviction
  redis监控
  [root@node1 ~]# redis-cli --stat
  ------- data ------ --------------------- load -------------------- - child -
  keys       mem      clients blocked requests            connections
  5          843.38K  3       0       52 (+0)             6
  5          843.38K  3       0       53 (+1)             6
  5          843.38K  3       0       54 (+1)             6
  5          843.38K  3       0       55 (+1)             6
  5          843.38K  3       0       56 (+1)             6
  5          843.38K  3       0       57 (+1)             6
  5          843.38K  3       0       58 (+1)             6
  5          843.38K  3       0       59 (+1)             6
  12、batchcommit性能优化
  一:redis 两点性能优化。。。
  1. 批量提交
   mset 。。。。 驱动,。。。。
  千人千面的时候,需要有一个数据初始化。。。
  400w - 500w customerid
  customerid_1  22
  customerid_2  21
  customerid_3  14
  操作400w  - 500w  tcp链接。。。。 几个G。。。  【1h】
   mset
  mset customerid_1 22  customerid_2  21  ....
  网络卡死 +  超时。。。。
  1w条提交一次。。。
  jedis来演示一下。
  public static void main(String[] args) {
  Jedis redis=new Jedis("192.168.23.155",6379);
  //String[] strlist=
  {"customerid_1","22","customerid_2","21","customerid_3","14"};
  ArrayList arrayList=new ArrayList();
  arrayList.add("customerid_1");
  arrayList.add("22");
  arrayList.add("customerid_2");
  arrayList.add("21");
  arrayList.add("customerid_3");
  arrayList.add("14");
  String[] strlist=new String[arrayList.size()];
  arrayList.toArray(strlist);
  redis.mset(strlist);   //batch
  System.out.println("success");
  }
  2. 多命令
  mset  string的批量
  hmset hash的批量
  sadd  set的批量
  如果做到三种命令的混合呢???
  set name jack
  hset person name jack
  sadd tags china
  这样的三条混合命令,如果一次性提交???  【节省的网络的轮回】
  pipeline 【管道】  redis。。。
  jedis来实现。。。
  package mytest2;
  import java.util.ArrayList;
  import redis.clients.jedis.Jedis;
  import redis.clients.jedis.Pipeline;

  public>  public static void main(String[] args) {
  Jedis redis=new Jedis("192.168.23.155",6379);
  //start pipeline
  Pipeline pipeline=redis.pipelined();
  pipeline.set("name","jack");
  pipeline.hset("person","name","mary");
  pipeline.sadd("tags", "china");
  pipeline.sync();   //execute....
  System.out.println("success");
  }
  }
  13、aof rdb 持久化
  redis默认是rdb模式
  一:redis序列化。
  memcached 没有序列化。。。
  1. rdb
  快照的模式。 mongodb。。。  【定点保存】如果重启会丢掉一些数据。。。。
  flush data to disk。。。
  redis默认就是rdb模式。。。
  触发机制:
  save time changes
  save 900 【15min】 1
  save 300 【3min】 10
  save 60 【1min】 10000
  在Redis中使用serverCron来实现这个检测。。。
  定期检测 三个save是否满足,如果满足,调用bgsave。。。
  手工进行save,bgsave 保存。。。
  ######非常重要#########################################
  save:同步保存,保存期间,client是被阻塞的。。。  #####
  #####
  int rdbSave(char *filename);                      #####
  #####
  bgsave:  开启子进程来保存。。。                  #####
  #####
  #######################################################
  2. aof
  来一条命令,保存一次。。。。 aof文件是保存我们的 。。。文本协议。。。
  默认是不启用的。
  如果开启:
  1. appendonly yes
  # appendfsync always     => 来一条保存一条。。 强制的执行fsync命令。。。  告诉操作系统强制flush到disk。    【slow,safe】 最多丢失一条数据
  appendfsync everysec     => 1秒 flush 一次。。。。  fsync命令  【折中】 最多丢失1s数据
  # appendfsync no         => flush。。。           fsync命令。。等待操作系统将自己缓冲区中的数据flush到硬盘。。。  【unsafe】  不知道。。。
  => select 0
  =>  set username  jack
  =>  set password 12345
  /* Trigger an AOF rewrite if needed */
  if (server.rdb_child_pid == -1 &&
  server.aof_child_pid == -1 &&
  server.aof_rewrite_perc &&
  server.aof_current_size > server.aof_rewrite_min_size)
  {
  long long base = server.aof_rewrite_base_size ?
  server.aof_rewrite_base_size : 1;
  long long growth = (server.aof_current_size*100/base) - 100;
  if (growth >= server.aof_rewrite_perc) {
  serverLog(LL_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
  rewriteAppendOnlyFileBackground();
  }
  }
  rewriteAppend:   如果db暴涨。。。redis命令是不是特别多。。。
  CURD操作。。。
  set username jack
  set username mary
  set username peter
  set username asdfasdf
  如果对username进行了100w操作。。。那命令多的吓人。。。
  所以redis做了一个机制,如果达到某一个阈值,会进行rewrite
  auto-aof-rewrite-percentage 100
  auto-aof-rewrite-min-size 64mb
  1. 如果你的文件有128M。。。   64 x 2 = 128
  生成快照 -> 生成命令到aof文件中。。。【缩小了文件的尺寸】
  14、master-slave
  一:redis:多机操作
  master - slave
  1. 数据的热备份
  如果master宕机了,slave还是有完整的备份。。。。 【热备份】
  2. 分解读写压力
  如果你的业务读写特别大。。。 【分流】
  分而治之。。。
  一般来说, 读写8:2   10个操作中有8个读,2个写。。。
  这时候,就有一个集群来抗读写操作。。。
  3. 可以在slave上做冷备份
  防止程序员,运维的误操作。。。比如说我做了flushall的操作。。。
  直接copy一个slave3 的rdb文件。。。
  mysql,sqlserver中 master - slave 概念
  nosql:基本上都有。。。
  二:实践
  用3台 Centos去做
  centos1: 192.168.23.158   master
  centos2: 192.168.23.152   slave1
  centos3: 192.168.23.145   slave2
  ######################
  配置非常简单,只要在从库设置如下内容即可 设置主库的ip及端口即可
  slaveof  
  (1)master主要配置如下:
  #bind 127.0.0.1
  protected-mode no
  port 6379
  #其他不用配置也可以
  (2)slave1配置如下:
  #bind 127.0.0.1
  protected-mode no
  port 6379
  slaveof 192.168.175.29 6379
  (3)salve2配置如下
  #bind 127.0.0.1
  protected-mode no
  port 6379
  slaveof 192.168.175.29 6379
  注意:这里具体的ip看你自己的了哦!!!!!
  redis-cli slaveof 命令
  修改配置文件 slaveof命令。。。
  # masterauth    如果master有密码,可以在这里配置。。。
  3257:M 28 Dec 06:28:53.339 * Slave 192.168.23.152:6379 asks for synchronization
  3257:M 28 Dec 06:28:53.339 * Full resync requested by slave 192.168.23.152:6379
  3257:M 28 Dec 06:28:53.339 * Starting BGSAVE for SYNC with target: disk
  3257:M 28 Dec 06:28:53.340 * Background saving started by pid 3376
  3376:C 28 Dec 06:28:53.349 * DB saved on disk
  3376:C 28 Dec 06:28:53.350 * RDB: 6 MB of memory used by copy-on-write
  3257:M 28 Dec 06:28:53.445 * Background saving terminated with success
  3257:M 28 Dec 06:28:53.446 * Synchronization with slave 192.168.23.152:6379
  succeeded
  三:验证
  # Replication
  role:master
  connected_slaves:2
  slave0:ip=192.168.23.152,port=6379,state=online,offset=127,lag=0
  slave1:ip=192.168.23.145,port=6379,state=online,offset=141,lag=0
  master_repl_offset:141
  repl_backlog_active:1
  repl_backlog_size:1048576
  repl_backlog_first_byte_offset:2
  repl_backlog_histlen:140
  # Keyspace
  127.0.0.1:6379> info Replication
  # Replication
  role:slave
  master_host:192.168.23.158
  master_port:6379
  master_link_status:up
  master_last_io_seconds_ago:5
  master_sync_in_progress:0
  slave_repl_offset:211
  slave_priority:100
  slave_read_only:1
  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
  127.0.0.1:6379>
  四:落地实践
  1.redis-cli
  通过验证,没有问题。。。
  2. C# client  =>  master - slave。。。。
  static void Main(string[] args)
  {
  //创建链接
  ConnectionMultiplexer redis =
  Connect("192.168.23.158:6379,192.168.23.152:6379,192.168.23.145:6379"
  );
  //获取db
  var database = redis.GetDatabase();
  //database.StringSet("username", "hellworld");
  var str = database.StringGet("username");
  }
  15、redis sentinel【哨兵】
  一:sentinel  【哨兵】
  master -> slave
  如果master挂掉了,,,程序只能读取,不能写入了。。。
  info:命令获取master集群的所有信息,比如说 slave的ip地址等信息。。。。
  主观: 个人的想法 【不一定真的下线】
  客观: 基本事实   【如果有某几个人都说master挂掉了,才是事实】
  二:搭建
  1. centos-1  192.168.23.158    master
  2. centos-2  192.168.23.152    slave1
  3. centos-3  192.168.23.145    slave2
  4. centos-4  192.168.23.154  放三台 sentinel。。。。
  《1》 sentinel:
  port
  monitor masterhost masterip
  客观下线: quorum  [阈值]
  主观下线: 下线的标准 【】 15s,30s。1min。。。
  其余的采用默认配置。。。
  sentinel auth-pass     =》 master 有密码,在这地方设置。。。
  sentinel monitor   
  port 26379
  sentinel down-after-milliseconds mymaster 30000
  protected-mode no  一定要关掉
  高可用的模式。。。你可以down 掉任何一台机器。。。sentinel会给我们重新选举select。。。
  C#,Java连接一下。。。  塞几个ip地址就ok了。。。
  一主2从搭建我就不说了
  下面说一下
  sentinel.conf
  只要配置如下内容
  (1)配置文件1
  protected-mode no
  port 26382
  sentinel monitor mymaster 192.168.23.158 6379 2
  (2)配置文件12
  protected-mode no
  port 26383
  sentinel monitor mymaster 192.168.23.158 6379 2
  (3)配置文件12
  protected-mode no
  port 26384
  sentinel monitor mymaster 192.168.23.158 6379 2
  分别在3台机器启动:
  ./redis-sentinel  sentinel.conf
  ./redis-sentinel  sentinel.conf
  ./redis-sentinel  sentinel.conf
  ps -ef | grep  redis
  当kill -9 master进程
  然后启动redis server时
  以前的master角色变成了slave角色
  sentinel【哨兵】从2个slave当中选一个当做master角色
  具体日志信息如下:
  10294:X 08 Mar 03:33:24.533 # +sdown master mymaster 192.168.175.29 6379
  10294:X 08 Mar 03:33:24.605 # +odown master mymaster 192.168.175.29 6379 #quorum 3/2
  10294:X 08 Mar 03:33:24.605 # +new-epoch 1
  10294:X 08 Mar 03:33:24.605 # +try-failover master mymaster 192.168.175.29 6379
  10294:X 08 Mar 03:33:24.624 # +vote-for-leader 3da9f7fdfda091e1d443fd5bbd8d77f3ac312016 1
  10294:X 08 Mar 03:33:24.624 # 38e1ed45641a1479dece7f06105be01246e694e1 voted for 38e1ed45641a1479dece7f06105be01246e694e1 1
  10294:X 08 Mar 03:33:24.633 # 1449d4f234e10a642c1155a68412e4ce529ba92f voted for 38e1ed45641a1479dece7f06105be01246e694e1 1
  10294:X 08 Mar 03:33:25.223 # +config-update-from sentinel 38e1ed45641a1479dece7f06105be01246e694e1 192.168.175.29 26384 @ mymaster 192.168.175.29 6379
  10294:X 08 Mar 03:33:25.223 # +switch-master mymaster 192.168.175.29 6379 192.168.175.29 6381
  10294:X 08 Mar 03:33:25.223 * +slave slave 192.168.175.29:6380 192.168.175.29 6380 @ mymaster 192.168.175.29 6381
  10294:X 08 Mar 03:33:25.223 * +slave slave 192.168.175.29:6379 192.168.175.29 6379 @ mymaster 192.168.175.29 6381
  10294:X 08 Mar 03:33:55.268 # +sdown slave 192.168.175.29:6379 192.168.175.29 6379 @ mymaster 192.168.175.29 6381
  这里的ip看你自己的ip
  16、redis监控
  一:redis的监控 【可视化的工具】
  学习连接
  http://www.cnblogs.com/huangxincheng/archive/2016/06/08/5571185.html
  winform
  web
  1. 程序员要经常用到的一个可视化监控工具。。。。
  mysql,sqlserver 都有一个可视化界面。。。
  Redis Desktop Manager
  Redis Client   【国人开发】  https://github.com/caoxinyu/RedisClient
  redisclient-win32.x86.2.0.exe
  有了可视化工具,就不用每次都输入命令去查看。。。
  Redis Studio
  二:web监控。。【redislive】
  github 源码地址如下:
  https://github.com/nkrode/RedisLive
  http://www.cnblogs.com/huangxincheng/archive/2016/06/08/5571185.html
  python 写的一个web监控。。。
  1. 安装pip =>  python的安装工具包。。。 C# nuge, java maven。。。
  下载:https://pypi.python.org/pypi/pip
  [root@localhost Desktop]# python
  Python 2.7.5 (default, Nov 20 2015, 02:00:19)
  [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  >>>
  2.python setup.py install  安装pip工具包
  3.pip install tornado   python server :【java tomcat,.net IIS】
  4. pip install redis    python redis驱动 【java jedis,.net StackExchange】
  5. pip install python-dateutil --upgrade   # python dateutil类库。。。 【java 工具类jar】
  6. 获取redislive的源代码  python的应用程序
  RedisServers: 你需要监控的redis server。。。。
  DataStoreType: RedisLive  【sqlite,redis】  专门开一台redis存放RedisLive的统计信息
  RedisStatsServer: 统计信息存放的Redis地址。。。
  7. 开启统计的redis
  8. 开启监控脚本  ./redis-monitor.py --duration=120
  9. 开启web站点   ./redis-live.py
  1083  mkdir /usr/local/python27
  1084  cd Python-2.7.5
  1085  ll
  1086  ./configure --prefix=/usr/local/python27
  1087  make
  1088  make install
  1089  python
  1090  mv /usr/bin/python /usr/bin/python2.6.6
  1091  ln -s /usr/local/python27/bin/python /usr/bin/python
  1132  tar zxvf setuptools-0.6c11.tar.gz
  1133  cd setuptools-0.6c11
  1134  python setup.py build
  1135  python setup.py install
  1136  cd ../pip-8.1.2
  1137  python setup.py  build
  1138  python setup.py  install
  [root@node1 soft]# find / -name python2.6
  /usr/include/python2.6
  /usr/lib64/python2.6
  /usr/lib/python2.6
  /usr/bin/python2.6
  三:怎么实现的。。
  RedisLive : monitor,info。。。。来构建一个趋势图。。。
  Redis Live is a dashboard application with a number of useful widgets. At it's heart is a monitoring script that periodically issues INFO and MONITOR command to the redis instances and stores the data for analytics.
  monitor.py 脚本。。。
  我的配置文件如下:
  [root@node2 RedisLive-master]# vim src/redis-live.conf
  {
  "RedisServers":
  [
  {
  "server": "192.168.175.29",
  "port" : 6379
  },
  {
  "server": "192.168.175.29",
  "port" : 6380
  },
  {
  "server": "192.168.175.29",
  "port" : 6381
  }
  ],
  "DataStoreType" : "redis",
  "RedisStatsServer":
  {
  "server" : "192.168.175.30",
  "port" : 6379
  }
  }
  17、redis cluster
  一: redis cluster 3.0 出来的
  1. 为什么集群:
  master -slave
  sentinel
  如果我的数据有1T。。。那如何存放到redis中。。。
  去重新化的方式
  mongodb
  monogd
  client       mongos    mongod
  mongod
  中心化
  redis: p2p的方法 【去重新化】
  1. 首先redis集群使用16384个slot。。。
  由三台机器承载16384个slot...
  client -> hash(username)
  0< hash(username) < 16383
  eg: hash(username)=100
  redis
  client   hash     redis
  redis
  这个hash(username)函数实在各自的client端。。。【驱动中内置的】
  2. cluster 内置了sentinel + master/slave + partition...
  3.
  4台centos
  centos1:  192.168.23.158
  centos2:  192.168.23.152
  centos3:  192.168.23.145
  centos4:  192.168.23.154     三台slave
  三:操作步骤:
  1. 开启cluster模式
  cluster-enabled yes                    开启集群状态
  cluster-config-file nodes-6379.conf    集群的节点文件
  ./redis-server ./redis.conf
  2. 找到一个叫做 redis-trib.rb 的文件 rb=>  ruby
  centos 没有ruby的环境。。。
  安装一系列的依赖包。。。
  //通过第三方工具进行安装
  ./redis-trib.rb create --replicas 1 192.168.23.158:6379 192.168.23.152:6379 192.168.23.145:6379 192.168.23.154:6379 192.168.23.154:6380 192.168.23.154:6381
  《1》 ruby环境
  《2》 ruby的redis驱动安装    gem install redis
  [root@localhost redis]# ./redis-trib.rb create --replicas 1 192.168.23.158:6379 192.168.23.152:6379 192.168.23.145:6379 192.168.23.154:6379 192.168.23.154:6380 192.168.23.154:6381
  >>> Creating cluster
  >>> Performing hash slots allocation on 6 nodes...
  Using 3 masters:
  192.168.23.158:6379
  192.168.23.152:6379
  192.168.23.145:6379
  Adding replica 192.168.23.154:6379 to 192.168.23.158:6379
  Adding replica 192.168.23.154:6380 to 192.168.23.152:6379
  Adding replica 192.168.23.154:6381 to 192.168.23.145:6379
  M: cbfadb06673f7eb69483aa2031cb60fc4251fb7a 192.168.23.158:6379
  slots:0-5460 (5461 slots) master
  M: 2160b439f59fafc3bb02fe920933284d5df3f39e 192.168.23.152:6379
  slots:5461-10922 (5462 slots) master
  M: 38a05510f8014d7fdf7b9c606461ecaae5a47b2a 192.168.23.145:6379
  slots:10923-16383 (5461 slots) master
  S: 2628c7fa7630d544b7d4a727d563a49c68578240 192.168.23.154:6379
  replicates cbfadb06673f7eb69483aa2031cb60fc4251fb7a
  S: 30c4755c49b228af5e111baa74dbebb85c4185c8 192.168.23.154:6380
  replicates 2160b439f59fafc3bb02fe920933284d5df3f39e
  S: 75a81dbaeb8d46b0783adb3ab8aeec405608ca18 192.168.23.154:6381
  replicates 38a05510f8014d7fdf7b9c606461ecaae5a47b2a
  Can I set the above configuration? (type 'yes' to accept):
  [root@localhost s1]# ./redis-cli
  127.0.0.1:6379> cluster nodes
  2628c7fa7630d544b7d4a727d563a49c68578240 192.168.23.154:6379 myself,slave cbfadb06673f7eb69483aa2031cb60fc4251fb7a 0 0 4 connected
  38a05510f8014d7fdf7b9c606461ecaae5a47b2a 192.168.23.145:6379 master - 0 1483019113842 3 connected 10923-16383
  75a81dbaeb8d46b0783adb3ab8aeec405608ca18 192.168.23.154:6381 slave 38a05510f8014d7fdf7b9c606461ecaae5a47b2a 0 1483019115859 6 connected
  30c4755c49b228af5e111baa74dbebb85c4185c8 192.168.23.154:6380 slave 2160b439f59fafc3bb02fe920933284d5df3f39e 0 1483019114335 5 connected
  cbfadb06673f7eb69483aa2031cb60fc4251fb7a 192.168.23.158:6379 master - 0 1483019114840 1 connected 0-5460
  2160b439f59fafc3bb02fe920933284d5df3f39e 192.168.23.152:6379 master - 0 1483019110809 2 connected 5461-10922
  127.0.0.1:6379>
  redis-cli做一个演示。。。  set username jack
  root@localhost s1]# ./redis-cli -c
  127.0.0.1:6379> set username jack
  -> Redirected to slot [14315] located at 192.168.23.145:6379
  OK
  192.168.23.145:6379> set password 12345
  -> Redirected to slot [9540] located at 192.168.23.152:6379
  OK
  192.168.23.152:6379> set email 3234234@qq.com
  OK
  192.168.23.152:6379>
  总结:学到这里算入门了!其他看个人修行了!!
  (1)机器准备
  机器            端口
  192.168.175.30 7000(主)
  192.168.175.30 7001(主)
  192.168.175.30 7002(主)
  192.168.175.30 7003(从)
  192.168.175.30 7004(从)
  192.168.175.30 7005(从)
  (2)6台配置如下:
  cluster-enabled yes                    开启集群状态
  cluster-config-file nodes-6379.conf    集群的节点文件
  并且改相应的端口。
  安装依赖
  yum install ruby
  (3)启动服务
  ./redis-server ./redis.conf &
  ./redis-trib.rb create --replicas 1 192.168.175.35:7000 192.168.175.35:7001 192.168.175.35:7002 192.168.175.35:7003 192.168.175.35:7004 192.168.175.35:7005
  http://www.iyunv.com/thread-18781-1-1.html
  https://rubygems.org/pages/download
  yum install -y rubygems
  gem install redis
  具体看官网
  https://redis.io/topics/cluster-tutorial
  http://blog.csdn.net/u013820054/article/details/51354189
  ./configure -prefix=/usr/local/ruby
  ##########################################################################################################################
  [root@node3 sbin]# ./redis-trib.rb create --replicas 1 192.168.175.35:7000 192.168.175.35:7001 192.168.175.35:7002 192.168.175.35:7003 192.168.175.35:7004 192.168.175.35:7005>>> Creating cluster
  >>> Performing hash slots allocation on 6 nodes...
  Using 3 masters:
  192.168.175.35:7000
  192.168.175.35:7001
  192.168.175.35:7002
  Adding replica 192.168.175.35:7003 to 192.168.175.35:7000
  Adding replica 192.168.175.35:7004 to 192.168.175.35:7001
  Adding replica 192.168.175.35:7005 to 192.168.175.35:7002
  M: 01c5a90a07bb271d47e8845f3952f0b16743cecd 192.168.175.35:7000
  slots:0-5460 (5461 slots) master
  M: 09f977342c6b09ed038522923b823676972418f2 192.168.175.35:7001
  slots:5461-10922 (5462 slots) master
  M: acb67e8e1473caccde89e3262900997e83d27d8a 192.168.175.35:7002
  slots:10923-16383 (5461 slots) master
  S: 7b544a3dbf307e0bc3be7bfd6b2a77369dd1a186 192.168.175.35:7003
  replicates 01c5a90a07bb271d47e8845f3952f0b16743cecd
  S: 0c591fed13413dbb7987025f75ff43c0db32ff17 192.168.175.35:7004
  replicates 09f977342c6b09ed038522923b823676972418f2
  S: bb2d0f0434ffa5e9b8cb8faed0d86d2d4b25a5ab 192.168.175.35:7005
  replicates acb67e8e1473caccde89e3262900997e83d27d8a
  Can I set the above configuration? (type 'yes' to accept): yes
  >>> Nodes configuration updated
  >>> Assign a different config epoch to each node
  >>> Sending CLUSTER MEET messages to join the cluster
  Waiting for the cluster to join....
  >>> Performing Cluster Check (using node 192.168.175.35:7000)
  M: 01c5a90a07bb271d47e8845f3952f0b16743cecd 192.168.175.35:7000
  slots:0-5460 (5461 slots) master
  1 additional replica(s)
  M: acb67e8e1473caccde89e3262900997e83d27d8a 192.168.175.35:7002
  slots:10923-16383 (5461 slots) master
  1 additional replica(s)
  M: 09f977342c6b09ed038522923b823676972418f2 192.168.175.35:7001
  slots:5461-10922 (5462 slots) master
  1 additional replica(s)
  S: 0c591fed13413dbb7987025f75ff43c0db32ff17 192.168.175.35:7004
  slots: (0 slots) slave
  replicates 09f977342c6b09ed038522923b823676972418f2
  S: bb2d0f0434ffa5e9b8cb8faed0d86d2d4b25a5ab 192.168.175.35:7005
  slots: (0 slots) slave
  replicates acb67e8e1473caccde89e3262900997e83d27d8a
  S: 7b544a3dbf307e0bc3be7bfd6b2a77369dd1a186 192.168.175.35:7003
  slots: (0 slots) slave
  replicates 01c5a90a07bb271d47e8845f3952f0b16743cecd
  [OK] All nodes agree about slots configuration.
  >>> Check for open slots...
  >>> Check slots coverage...
  [OK] All 16384 slots covered.
  redis 192.168.175.35:7000> cluster info
  "cluster_state:ok\r\ncluster_slots_assigned:16384\r\ncluster_slots_ok:16384\r\ncluster_slots_pfail:0\r\ncluster_slots_fail:0\r\ncluster_known_nodes:6\r\ncluster_size:3\r\ncluster_current_epoch:6\r\ncluster_my_epoch:1\r\ncluster_stats_messages_sent:256\r\ncluster_stats_messages_received:256\r\n"
  redis 192.168.175.35:7000> cluster nodes
  "acb67e8e1473caccde89e3262900997e83d27d8a 192.168.175.35:7002 master - 0 1489409919371 3 connected 10923-16383\n09f977342c6b09ed038522923b823676972418f2 192.168.175.35:7001 master - 0 1489409918315 2 connected 5461-10922\n0c591fed13413dbb7987025f75ff43c0db32ff17 192.168.175.35:7004 slave 09f977342c6b09ed038522923b823676972418f2 0 1489409915217 5 connected\nbb2d0f0434ffa5e9b8cb8faed0d86d2d4b25a5ab 192.168.175.35:7005 slave acb67e8e1473caccde89e3262900997e83d27d8a 0 1489409917264 6 connected\n7b544a3dbf307e0bc3be7bfd6b2a77369dd1a186 192.168.175.35:7003 slave 01c5a90a07bb271d47e8845f3952f0b16743cecd 0 1489409921497 4 connected\n01c5a90a07bb271d47e8845f3952f0b16743cecd 192.168.175.35:7000 myself,master - 0 0 1 connected 0-5460\n"
  [root@node3 sbin]# redis-cli -p 7000 cluster nodes | grep master
  acb67e8e1473caccde89e3262900997e83d27d8a 192.168.175.35:7002 master - 0 1489414087200 3 connected 10923-16383
  09f977342c6b09ed038522923b823676972418f2 192.168.175.35:7001 master - 0 1489414088131 2 connected 5461-10922
  01c5a90a07bb271d47e8845f3952f0b16743cecd 192.168.175.35:7000 myself,master - 0 0 1 connected 0-5460
  ################
  [root@node3 sbin]# pwd
  /root/soft/7000/redis/sbin
  [root@node3 sbin]# ./redis-cli  -c -p 7000
  127.0.0.1:7000>
  [root@node3 sbin]# ./redis-cli  --help
  redis-cli 3.2.6
  Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
  -h       Server hostname (default: 127.0.0.1).
  -p           Server port (default: 6379).
  -s         Server socket (overrides hostname and port).
  -a       Password to use when connecting to the server.
  -r         Execute specified command N times.
  -i       When -r is used, waits  seconds per command.
  It is possible to specify sub-second times like -i 0.1.
  -n             Database number.
  -x                 Read last argument from STDIN.
  -d      Multi-bulk delimiter in for raw formatting (default: \n).
  -c                 Enable cluster mode (follow -ASK and -MOVED redirections).
  --raw              Use raw formatting for replies (default when STDOUT is
  not a tty).
  --no-raw           Force formatted output even when STDOUT is not a tty.
  --csv              Output in CSV format.
  --stat             Print rolling stats about server: mem, clients, ...
  --latency          Enter a special mode continuously sampling latency.
  --latency-history  Like --latency but tracking latency changes over time.
  Default time interval is 15 sec. Change it using -i.
  --latency-dist     Shows latency as a spectrum, requires xterm 256 colors.
  Default time interval is 1 sec. Change it using -i.
  --lru-test   Simulate a cache workload with an 80-20 distribution.
  --slave            Simulate a slave showing commands received from the master.
  --rdb    Transfer an RDB dump from remote server to local file.
  --pipe             Transfer raw Redis protocol from stdin to server.
  --pipe-timeout  In --pipe mode, abort with error if after sending all data.
  no reply is received within  seconds.
  Default timeout: 30. Use 0 to wait forever.
  --bigkeys          Sample Redis keys looking for big keys.
  --scan             List all keys using the SCAN command.
  --pattern     Useful with --scan to specify a SCAN pattern.
  --intrinsic-latency  Run a test to measure intrinsic system latency.
  The test will run for the specified amount of seconds.
  --eval       Send an EVAL command using the Lua script at .
  --ldb              Used with --eval enable the Redis Lua debugger.
  --ldb-sync-mode    Like --ldb but uses the synchronous Lua debugger, in
  this mode the server is blocked and script changes are
  are not rolled back from the server memory.
  --help             Output this help and exit.
  --version          Output version and exit.
  Examples:
  cat /etc/passwd | redis-cli -x set mypasswd
  redis-cli get mypasswd
  redis-cli -r 100 lpush mylist x
  redis-cli -r 100 -i 1 info | grep used_memory_human:
  redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
  redis-cli --scan --pattern '*:12345*'
  (Note: when using --eval the comma separates KEYS[] from ARGV[] items)
  When no command is given, redis-cli starts in interactive mode.
  Type "help" in interactive mode for information on available commands
  and settings.


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-630431-1-1.html 上篇帖子: redis主从复制和故障切换 下篇帖子: redis主从服务配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表