❶ redis 数据库中查看有哪些数据
使用info查看Keyspace
代表有多少个库或键名空间,然后select 相应的id选择库,
scan 0查询所有的键。
❷ 查询数据放入了redis中缓存,怎么查看缓存的数据
普通分页
一般分页做缓存都是直接查找出来,按页放到缓存里,但是这种缓存方式有很多缺点。
如缓存不能及时更新,一旦数据有变化,所有的之前的分页缓存都失效了。
比如像微博这样的场景,微博下面现在有一个顶次数的排序。这个用传统的分页方式很难应对。
一种思路
最近想到了另一种思路。
数据以ID为key缓存到Redis里;
把数据ID和排序打分存到Redis的skip list,即zset里;
当查找数据时,先从Redis里的skip list取出对应的分页数据,得到ID列表。
用multi get从redis上一次性把ID列表里的所有数据都取出来。如果有缺少某些ID的数据,再从数据库里查找,再一块返回给用户,并把查出来的数据按ID缓存到Redis里。
在最后一步,可以有一些小技巧:
比如在缺少一些ID数据的情况下,先直接返回给用户,然后前端再用ajax请求缺少的ID的数据,再动态刷新。
❸ 怎么判断redis中有没有数据
redis-cli 中。 使用 info Keyspace 查看存储数据的相关信息。 通过 keys * 查看所有的 key
❹ 如何在linux中查询redis的数据
1、执行如图是命令,查看redis服务是否启动。
❺ 如何查询redis存储的所有数据
1、打开reidis,选择第三个数据库。
❻ 如何通过命令查看redis数据
如何查看redis最近使用的命令使用redis的脚本功能实现redis中数据简单查询,有需要的朋友可以参考下。在redis的设计中,key是一切,对于redis是可见的,而value对于redis来说就是一个字节数组,redis并不知道你的value中存储的是什么,所以要
❼ 查看redis 中有多少条数据
使用Redis的脚本功能实现Redis中数据简单查询,有需要的朋友可以参考下。
在Redis的设计中,key是一切,对于Redis是可见的,而value对于Redis来说就是一个字节数组,Redis并不知道你的value中存储的是什么,所以要想实现比如
‘select * from users where user.location="shanghai"’
这样的查询,在Redis是没办法通过value进行比较得出结果的。但是可以通过不同的数据结构类型来做到这一点。比如如下的数据定义
users:1 {name:Jack,age:28,location:shanghai} users:2 {name:Frank,age:30,location:beijing} users:location:shanghai [1]
其中users:1 users:2 分别定义了两个用户信息,通过Redis中的hash数据结构,而users:location:shanghai 记录了所有上海的用户id,通过集合数据结构实现。这样通过两次简单的Redis命令调用就可以实现我们上面的查询。
Jedis jedis = jedisPool.getResource(); Set<String> shanghaiIDs = jedis.smembers("users:location:shanghai"); //遍历该set //... //通过hgetall获取对应的user信息 jedis.hgetAll("users:" + shanghaiIDs[0]);
通过诸如以上的设计,可以实现简单的条件查询。但是这样的问题也很多,首先需要多维护一个ID索引的集合,其次对于一些复杂查询无能为力(当然也不能期望Redis实现像关系数据库那样的查询,Redis不是干这的)。
但是Redis2.6集成了Lua脚本,可以通过eval命令,直接在RedisServer环境中执行Lua脚本,并且可以在Lua脚本中调用Redis命令。其实,就是说可以让你用Lua这种脚本语言,对Redis中存储的key value进行操作,这个意义就大了,甚至可以将你们系统所需的各种业务写成一个个lua脚本,提前加载进入Redis,然后对于请求的响应,只需要调用一个个lua脚本就行。当然这样说有点夸张,但是意思就是这样的。
比如,现在我们要实现一个‘所有age大于28岁的user’这样一个查询,那么通过以下的Lua脚本就可以实现
public static final String SCRIPT = "local resultKeys={};" + "for k,v in ipairs(KEYS) do " + " local tmp = redis.call('hget', v, 'age');" + " if tmp > ARGV[1] then " + " table.insert(resultKeys,v);" + " end;" + "end;" + "return resultKeys;";
执行脚本代码 Jedis jedis = jedisPool.getResource(); jedis.auth(auth); List<String> keys = Arrays.asList(allUserKeys); List<String> args = new ArrayList<>(); args.add("28"); List<String> resultKeys = (List<String>)jedis.evalsha(funcKey, keys, args); return resultKeys;
注意,以上的代码中使用的是evalsha命令,该命令参数的不是直接Lua脚本字符串,而是提前已经加载到Redis中的函数的一个SHA索引,通过以下的代码将系统中所有需要执行的函数提前加载到Redis中,我们的系统维护一个函数哈希表,后续需要实现什么功能,就从函数表中获取对应功能的SHA索引,通过evalsha调用就行。
String shaFuncKey = jedis.scriptLoad(SCRIPT);//加载脚本,获取sha索引 funcTable.put(funcName_age, shaFuncKey);//添加到函数表中
通过以上的方法,便可以使较为复杂的查询放到Redis中去执行,提高效率。
❽ 如何查看存储空间数据库redis中的数据
使用Redis的脚本功能实现Redis中数据简单查询,有需要的朋友可以参考下。 在Redis的设计中,key是一切,对于Redis是可见的,而value对于Redis来说就是一个字节数组,Redis并不知道你的value中存储的是什么
❾ Redis有哪些数据类型
一、String | 字符串类型
Redis的字符串类型,可以存储字符串、整数或浮点数,如果存储的是整数或者浮点数,还能执行自增或自减操作。Reids的string类型是二进制的,可以包含任何数据,比如一个序列化的对象、一个图片、字节流等,不过存储大小上限是512M。
Redis底层定义了自己的一种数据结构。
二、List | 列表类型
Redis的列表类型和许多编程语言中的列表类型类似,可以有序地存储多个字符串,支持从列表的左端和右端推入或弹出元素,Redis列表的底层实现是压缩列表,Redis内容自己实现的数据结构和双端链表。
将一个或者多个value值插入列表的表头。如果 key 不存在,会创建一个空列表并执行 LPUSH 操作。当 key
存在但不是列表类型时,返回一个错误。
三、set | 集合类型
Redis的集合以无序的方式存储多个不同的元素,这里要注意的是无序和不同。除了对集合能快速执行添加、删除、检查一个元素是否在集合中之外,还可以对多个集合执行交集、并集和差集运算。
Redis的集合类型底层实现主要是通过一种叫做字典的数据结构。不过Redis为了追求极致的性能,会根据存储的值是否是整数,选择一种intset的数据结构。当满足一定条件后,会切换成字典的实现。
四、hash | 散列表(哈希表)
Redis的hash类型其实就是一个缩减版的redis。它存储的是键值对,将多个键值对存储到一个redis键里面。
hash类型的底层主要也是基于字典这种数据结构来实现的。
五、zset | 有序集合
有序集合相比较于集合,多个有序两个字,我们知道set集合类型存储的元素是无序的,那Redis有序集合是怎么保证有序的?使用分值,有序集合里存储这成员与分值之间的映射,并提供了分值处理命令,以及根据分值的大小有序地获取成员或分值的命令。
Redis有序集合的实现使用了一种叫跳跃表的数据结构(简称跳表,可自行查阅),同时也使用到了前面提到的压缩列表。也是满足一定条件的话,会自行转换。
❿ 怎么样使用Redis来存储和查询ip数据
今天朋友打了个电话,他们网站的业务要根据客户的ip地址快速定位客户的地理位置。网上已经有一大堆类似的ip地址库可以用,但问题是这些地址库的数据表结构大多如下所示
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| ip_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| ip_country | varchar(50) | NO | | NULL | |
| ip_startip | bigint(11) | NO | MUL | NULL | |
| ip_endip | bigint(11) | NO | MUL | NULL | |
| country_code | varchar(2) | NO | | NULL | |
| zone_id | int(11) | NO | | 0 | |
+--------------+------------------+------+-----+---------+----------------+
最核心的部分是三个: ip_startip , ip_endip 以及 ip_id 。其中 ip_id 是要查询的结果,当然也可以把 zone_id 和 ip_country 包括进去。这里就用 ip_id 来特指查询结果了。
面对这个表,没什么其它办法,查询语句只能是
SELECT * FROM who_ip WHERE ip_startip <= {ip} AND ip_endip >= {ip}
其中 {ip} 是要查询的ip地址,为了方便查询,在php中一般要用 ip2long函数把它转换为一个整数。现在问题来了,这个表有400万条数据,无论你怎么优化它的索引结构(实际上我觉得这没啥用),在以上查询语句中都要耗费2秒以上的时间,对于一个高频使用的接口,这显然是不可忍受的。
REDIS能不能解决这个问题。实际上这也是朋友最关心的问题,因为知道Redis有强大数据结构和超快的速度,那么能不能设计出适应这种查询场景的结构。
范围查询,首先想到的就是Redis里面的 Sorted Sets 结构,这也是redis中唯一可以指定范围( SCORE 值)查询的结构了,所以基本上希望都寄托在它身上了。
最简单粗暴的方法就是把 ip_startip 和 ip_endip 都转化为 Sorted Sets 里的 Score ,然后把 ip_id 定义为 Member 。这样我们的查询就很简单了,只需要用 ZRANGESCORE 查询出离ip最近SCORE对应的两个 ip_id 即可。然后再分析,如果这两个 ip_id 是相同的,那么说明这个ip在这个地址段,如果不同的话证明这个ip地址没有被任何地址段所定义,是一个未知的ip。
基本逻辑是没有问题的,但是最大的问题还是性能上的挑战。根据我的经验,一个SET 里面放10万条数据以上就已经很慢了,如果放到400万这种量级,我非常怀疑它跟mysql相比还有优势吗?
我设计的存储结构
我的解决方案是把这个地址库切分,每一片区最多保存65536个地址。也就是说如果一个ip地址段为 188.88.77.22 - 188.90.78.10 ,那么我们就把它切分为
188.88.77.22 - 188.88.77.255
188.89.0.0 - 188.89.255.255
188.90.0.0 - 189.90.78.10
也就是我们保证每一个ip地址段都被保存在 xxx.xxx.0.0 - xxx.xxx.255.255的一个区段中,这个区段的理论极限是保存65536个值,实际上要远小于这个数字。而这样的区段理论上也有65536个,这都是ip地址的设计所限,当然实际上也远小于这个值。
因此这样的设计基本上就能满足我们的性能需要了。以下是我用php写的数据切分程序
<?php
// redis 参数
define('REDIS_HOST', '127.0.0.1');
define('REDIS_PORT', 6379);
define('REDIS_DB', 10);
define('MYSQL_HOST', 'localhost');
define('MYSQL_PORT', 3306);
define('MYSQL_USER', 'root');
define('MYSQL_PASS', '123456');
define('MYSQL_DB', 'who_brand');
define('MYSQL_TABLE', 'who_ip');
define('MYSQL_COLUMN_START', 'ip_startip');
define('MYSQL_COLUMN_END', 'ip_endip');
define('MYSQL_COLUMN_ID', 'ip_id');
define('MYSQL_PAGESIZE', 1000);
mysql_connect(MYSQL_HOST . ':' . MYSQL_PORT, MYSQL_USER, MYSQL_PASS);
mysql_select_db(MYSQL_DB);
function add_ip($page, $offset, $value) {
static $redis;
if (!$redis) {
$redis = new Redis();
$redis->connect(REDIS_HOST, REDIS_PORT);
$redis->select(REDIS_DB);
}
$key = 'ip:' . $page;
$redis->zAdd($key, $offset, $value);
}
$page = 0;
do {
$offset = $page * MYSQL_PAGESIZE;
$count = 0;
$res = mysql_query('SELECT * FROM ' . MYSQL_TABLE . ' LIMIT ' . MYSQL_PAGESIZE . " OFFSET {$offset}");
while ($ip = mysql_fetch_assoc($res)) {
$start = $ip[MYSQL_COLUMN_START];
$end = $ip[MYSQL_COLUMN_END];
$value = $ip[MYSQL_COLUMN_ID];
$startOffset = $start % 65536;
$endOffset = $end % 65536;
$start -= $startOffset;
$end -= $endOffset;
$startPage = $start / 65536;
$endPage = $end / 65536;
for ($i = $startPage; $i <= $endPage; $i ++) {
if ($i == $startPage) {
add_ip($i, $startOffset, 's:' . $value);
if ($i != $endPage) {
add_ip($i, 65535, 'e:' . $value);
}
}
if ($i == $endPage) {
add_ip($i, $endOffset, 'e:' . $value);
if ($i != $startPage) {
add_ip($i, 0, 's:' . $value);
}
}
if ($i != $endPage && $i != $startPage) {
add_ip($i, 0, 's:' . $value);
add_ip($i, 65535, 'e:' . $value);
}
}
echo ($page * MYSQL_PAGESIZE + $count) . "\n";
$count ++;
}
$page ++;
} while ($count = MYSQL_PAGESIZE);
<?php
define('REDIS_HOST', '127.0.0.1');
define('REDIS_PORT', 6379);
define('REDIS_DB', 10);
$redis = new Redis();
$redis->connect(REDIS_HOST, REDIS_PORT);
$redis->select(REDIS_DB);
$ip = ip2long('173.255.218.70');
$offset = $ip % 65536;
$page = ($ip - $offset) / 65536;
// 取出小于等于它的最接近值
$start = $redis->zRevRangeByScore('ip:' . $page, 0, $offset, array(
'limit' => array(0, 1)
));
// 取出大于等于它的最接近值
$end = $redis->zRangeByScore('ip:' . $page, $offset, 65535, array(
'limit' => array(0, 1)
));
if (empty($start) || empty($end)) {
echo 'unknown';
exit;
}
$start = $start[0];
$end = $end[0];
list ($startOp, $startId) = explode(':', $start);
list ($endOp, $endId) = explode(':', $end);
if ($startId != $endId) {
echo 'unknown';
exit;
}
echo $startId;