Redis
🗃️

Redis

Tag
Database
Last Edited Time
Dec 20, 2021 08:54 PM
Created
Nov 26, 2020 04:28 AM

General

使用Redis存储用户粉丝,该使用哪种数据类型?Hash or Sorted Set ?
之前看了唐福林 新浪微博开放平台中的Redis实践 的公开视频 其中讲到存储用户粉丝信息使用的是Redis的hash类型,每个用户一张hash表来存储粉丝。为了方便对关注时间进行排序,用hash表的fields存储粉丝ID,value存储关注时间。 我想大概是这样: key: 用户ID加前后缀 field: 粉丝ID value:关注时间 ...... 但是使用这种方法时我发现hash是无序状态的,也就是 每次要获取最新的几个粉丝都需要获取所有的粉丝,然后遍历按时间戳进行排序 。 而我又发现了另一种数据类型 有序集合(sorted set) 如果使用Sort Set数据类型存储粉丝列表的话就方便多了。 依然使用当前用户ID加前后缀作Key,以粉丝的ID作member,关注时间作score。也一样可以用来存储用户粉丝,而且 有序集合(sorted set)的命令更加灵活,根据score排序,筛选等非常方便 。 key: 用户ID加前后缀 member: 粉丝ID score:关注时间 ...... 那么问题来了:新浪微博为什么会采取第一种方式来存储粉丝(2011年,现在不知道了)? 第一种方式有哪些优势,第二种方式又有哪些弊端呢? 如果我说两种方式结合到一起呢? 另外hash,你的理解是错误的。 hash不像数据库或者excel,一个hash存储的虽然是多个字段,但不是多行数据且每行多个字段 你上述的应该这么去做: 假设当前用户ID为1; 首先:依靠有序集合实现好友关系(对应的score就是关注时间戳),假设与用户ID:2,3,4为好友 其次:使用hash去记录好友的具体信息(多个hash),存储规则如下: # 存储规则如下 user:uid:fans:fuid:info #user:用户ID:fans:好友ID:info # 那对应2,3,4的三个hash存储,就是 user:1:fans:2:info user:1:fans:3:info user:1:fans:4:info
使用Redis存储用户粉丝,该使用哪种数据类型?Hash or Sorted Set ?

Centos7

Install

Reference:
Vim conf
vi /etc/redis.conf
注释这一行:
#bind 127.0.0.1 foobared即当前密码,可以自行修改为
requirepass foobared
// 端口监听
ss -nlp|grep redis
systemctl start redis.service #启动redis服务器

systemctl stop redis.service #停止redis服务器

systemctl restart redis.service #重新启动redis服务器

systemctl status redis.service #获取redis服务器的运行状态

systemctl enable redis.service #开机启动redis服务器

systemctl disable redis.service #开机禁用redis服务器

远程连接失败

防火墙关闭
systemctl stop firewalld.service           #停止firewall
systemctl disable firewalld.service     #禁止firewall开机启动
systemctl enable firewalld.service 
或开启端口:
sudo firewall-cmd --zone=public --add-port=6379/tcp --permanent
sudo firewall-cmd --reload

连接

!需要先安装有redis的cli
redis-cli
// 远程
redis-cli -h host -p port -a password

数据

207.246.94.177:6379
密码207207
 
 

Java

JedisPool

jedis:连接池(JedisPool)使用示例_10km的专栏-CSDN博客
Jedis实例不是线程安全的,所以不可以多个线程共用一个Jedis实例,但是创建太多的实现也不好因为这意味着会建立很多sokcet连接。 JedisPool是一个线程安全的网络连接池。可以用JedisPool创建一些可靠Jedis实例,可以从池中获取Jedis实例,使用完后再把Jedis实例还回JedisPool。这种方式可以避免创建大量socket连接并且会实现高效的性能. JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(10); pool = new JedisPool(jedisPoolConfig, "localhost"); 1. JedisPool#getResource()方法从连接池中取得一个Jedis实例, 2.使用Jedis实例进行正常的数据操作 3.Jedis实例使用完后要把它再放回连接池。 关于如何将使用完后的Jedis实例还回连接池,网上看到的大部分文章都是建议用 JedisPool#returnResource 方法,这些文章大多是3,4年前的文章 jedis官网: https://github.com/xetorthio/jedis , 而当我使用jedis时,jedis的最新版本已经到了2.9(我使用的是2.8.2)。 在jedis2.8.2中已经将 JedisPool#returnResource方法废弃了,并明确说明这个方法的功能由 Jedis.close() 方法代替。 如果进一步查看 Jedis#close()方法的源码,会发现, close()方法最终依然是调用 JedisPool#returnResource方法。 可以看到,当使用JedisPool时,close方法并没有真的执行client.close方法,只是将它还给JedisPool连接池,以供下次使用。 所以正确使用并释放连接池资源的方式如下: 《Java中使用Jedis操作Redis》 《JedisPool介绍》
jedis:连接池(JedisPool)使用示例_10km的专栏-CSDN博客

简介

Jedis实例不是线程安全的,所以不可以多个线程共用一个Jedis实例,但是创建太多的实现也不好因为这意味着会建立很多sokcet连接。
JedisPool是一个线程安全的网络连接池。可以用JedisPool创建一些可靠Jedis实例,可以从池中获取Jedis实例,使用完后再把Jedis实例还回JedisPool。这种方式可以避免创建大量socket连接并且会实现高效的性能.
 
💡
Jedis 实现了java.lang.AutoCloseable接口,所以这里可以用java 1.7 try-with-resources语法自动完成close
public void testPing(){
      // Jedis 实现了java.lang.AutoCloseable接口,所以这里可以用java 1.7 try-with-resources语法自动完成close
      try(Jedis jedis = jedisPool.getResource()){
          //查看服务是否运行 PING
          System.out.println("服务正在运行: "+jedis.ping());
      }
  }

Code

 

Isuues

 

Loading Comments...