Kyligence AI 服务 - 让大模型完成准确、可靠的数值计算和回答! 立即了解更多
AI 数智助理
Kyligence Zen Kyligence Zen
Kyligence Enterprise Kyligence Enterprise
Kyligence Turbo Kyligence Turbo
指标平台解决方案
OLAP 解决方案
行业解决方案
客户总览
金融
零售
制造
医药
其他
云平台
BI
寻求合作
资源
Kyligence Enterprise
Kyligence Zen
培训
Apache Kylin
Byzer
Gluten
博客
关于
市场活动
使用 Kylin 2.6.4 之前的版本并且以 Memcached 作为查询缓存时,即有概率触发 Memcached IO 线程死亡问题,本文作者为大家分享了如何通过实验一步步排查,找出问题根源,并通过非常简单的方式解决这一 bug 的过程。
前提条件
使用 Kylin 2.6.4 之前的版本并且使用 Memcached 作为查询缓存,即有概率触发该问题。
故障现象
Kylin 实例响应很慢,日志中出现如下信息:
2019-07-01 15:21:18,024 INFO [Query 3f75c477-9c38-35bf-24a0-656459d9ebb1-212641] v2.CubeHBaseEndpointRPC:188 : Query-3f75c477-9c38-35bf-24a0-656459d9ebb1: try to get segment result from cache for segment:******[20150901000000_20160101000000]2019-07-01 15:21:20,028 INFO [Query 3f75c477-9c38-35bf-24a0-656459d9ebb1-212641] v2.CubeHBaseEndpointRPC:197 : Query-3f75c477-9c38-35bf-24a0-656459d9ebb1: no segment result is cached for segment:******[20150901000000_20160101000000], take time:2000ms
2019-07-01 15:21:18,024 INFO [Query 3f75c477-9c38-35bf-24a0-656459d9ebb1-212641] v2.CubeHBaseEndpointRPC:188 : Query-3f75c477-9c38-35bf-24a0-656459d9ebb1: try to get segment result from cache for segment:******[20150901000000_20160101000000]
2019-07-01 15:21:20,028 INFO [Query 3f75c477-9c38-35bf-24a0-656459d9ebb1-212641] v2.CubeHBaseEndpointRPC:197 : Query-3f75c477-9c38-35bf-24a0-656459d9ebb1: no segment result is cached for segment:******[20150901000000_20160101000000], take time:2000ms
初步认定为在 try to get segment result 时,发生超时(2秒正好是默认超时时间)。但检查 Memcached 各个实例,发现均为可用状态。
该问题在访问分区 Cube 时会被严重放大,因为一个 Segment 访问超时时间是 2 秒,当 Cube 存在 20 个的 Segment 时,一条 SQL 至少要 40 秒才能返回结果。
因此最近几次故障发生时,未分区的全量 Cube 几乎无感知,但分区的 Cube 基本均全处于不可用状态。
此外,异常发生前日志中持续打印下列信息:
2019-07-04 13:59:48.989 INFO net.spy.memcached.MemcachedConnection: Reconnecting due to exception on {QA sa=******, #Rops=0, #Wops=2, #iq=0, topRop=null, topWop=Cmd: 1 Opaque: 2297 Key: PROD:query_segment_cache:36b344a063b0f914448b311229db4c4d3a2b30c2 Cas: 0 Exp: 604800 Flags: 2048 Data Length: 350795, toWrite=0, interested=4}java.lang.NullPointerException2019-07-04 13:59:48.992 WARN net.spy.memcached.MemcachedConnection: Closing, and reopening {QA sa=******, #Rops=0, #Wops=2, #iq=0, topRop=null, topWop=Cmd: 1 Opaque: 2297 Key: PROD:query_segment_cache:36b344a063b0f914448b311229db4c4d3a2b30c2 Cas: 0 Exp: 604800 Flags: 2048 Data Length: 350795, toWrite=0, interested=4}, attempt 0.2019-07-04 13:59:48.993 INFO net.spy.memcached.protocol.binary.BinaryMemcachedNodeImpl: No buffer for current write op, removing2019-07-04 13:59:50.123 INFO net.spy.memcached.MemcachedConnection: Reconnecting due to exception on {QA sa=******, #Rops=1, #Wops=1, #iq=0, topRop=null, topWop=Cmd: -1 Opaque: -1 Keys: , toWrite=0, interested=4}java.lang.NullPointerException atnet.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer(TCPMemcachedNodeImpl.java:206) atnet.spy.memcached.MemcachedConnection.handleWrites(MemcachedConnection.java:811) atnet.spy.memcached.MemcachedConnection.handleInputQueue(MemcachedConnection.java:596) atnet.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:423) atnet.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457) at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457)
2019-07-04 13:59:48.989 INFO net.spy.memcached.MemcachedConnection: Reconnecting due to exception on {QA sa=******, #Rops=0, #Wops=2, #iq=0, topRop=null, topWop=Cmd: 1 Opaque: 2297 Key: PROD:query_segment_cache:36b344a063b0f914448b311229db4c4d3a2b30c2 Cas: 0 Exp: 604800 Flags: 2048 Data Length: 350795, toWrite=0, interested=4}java.lang.NullPointerException
2019-07-04 13:59:48.992 WARN net.spy.memcached.MemcachedConnection: Closing, and reopening {QA sa=******, #Rops=0, #Wops=2, #iq=0, topRop=null, topWop=Cmd: 1 Opaque: 2297 Key: PROD:query_segment_cache:36b344a063b0f914448b311229db4c4d3a2b30c2 Cas: 0 Exp: 604800 Flags: 2048 Data Length: 350795, toWrite=0, interested=4}, attempt 0.
2019-07-04 13:59:48.993 INFO net.spy.memcached.protocol.binary.BinaryMemcachedNodeImpl: No buffer for current write op, removing
2019-07-04 13:59:50.123 INFO net.spy.memcached.MemcachedConnection: Reconnecting due to exception on {QA sa=******, #Rops=1, #Wops=1, #iq=0, topRop=null, topWop=Cmd: -1 Opaque: -1 Keys: , toWrite=0, interested=4}java.lang.NullPointerException atnet.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer(TCPMemcachedNodeImpl.java:206)
atnet.spy.memcached.MemcachedConnection.handleWrites(MemcachedConnection.java:811)
atnet.spy.memcached.MemcachedConnection.handleInputQueue(MemcachedConnection.java:596)
atnet.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:423)
atnet.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457) at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457)
重启后,该故障可 100% 解决。如果不重启,该状态持续一段时间后也会自动触发 OOM 然后被进程管理工具自动重启。
初步确定原因
经过对 Memcached 的多次压测,响应时间最高不超过 50 ms,因此初步排除 Memcached 真的响应过慢导致 Kylin Memcached 客户端 2000 ms 超时的可能。
后开始检查 Kylin 操作 Memcached 的相关逻辑,也并未发现明显异常。
最终开启测试实例加载真实数据,进行 Debug,重复执行生产环境 Kylin 实例发生异常前几十秒正在执行的 SQL,最终成功复现线上 2000 ms 超时的问题。
通过检查测试 Kylin 实例中正在运行的线程,终于发现异常。处理 Memcached IO 的线程竟然不存在了。
然后从断点中观察到 Memcached IO 队列中发现大量积压,无法读出也无法写入。
且终端打印出异常信息:
Exception in thread "Memcached IO over {MemcachedConnection to ******}" java.lang.NullPointerException at net.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer(TCPMemcachedNodeImpl.java:206) at net.spy.memcached.MemcachedConnection.handleWrites(MemcachedConnection.java:811) at net.spy.memcached.MemcachedConnection.handleInputQueue(MemcachedConnection.java:596) at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:423) at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457)
Exception in thread "Memcached IO over {MemcachedConnection to ******}" java.lang.NullPointerException
at net.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer(TCPMemcachedNodeImpl.java:206)
at net.spy.memcached.MemcachedConnection.handleWrites(MemcachedConnection.java:811)
at net.spy.memcached.MemcachedConnection.handleInputQueue(MemcachedConnection.java:596)
at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:423)
at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457)
所以基本确定,造成故障的原因为负责对 Memcached 进行 IO 操作的线程异常退出。
进一步找出问题根源
通过查看 Memcached 客户端 Spymemcached 的源码,并无法成功找出可能造成 Memcached IO 线程 NPE 退出的原因。正当百思不得其解之际,在 GitHub 中发现了下面这个 Pull Request:
NPE in fillWriteBuffer() with binary protocol
(https://github.com/couchbase/spymemcached/pull/17)
顺便吐槽 spymemcached 的 issue tracker 真心难找,这个 PR 的作者是拿 PR 来报 Issue 的。
读完之后恍然大悟,只有在写入的数据大于等于 1024 * 1024 byte 即 1 MB 时,才可能触发该异常。
但是大于 1 MB 的数据是写不进去的,所以基本可以推测出 Kylin 的客户端一定是大量并发的写入极接近 1 MB 或等于 1 MB 的数据时,触发了这个异常,导致 Memcached IO 线程死亡。
但是查看了 Kylin 的源码发现下面的信息,又使我陷入了沉思。。。
private SegmentQueryCache() { KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv(); MemcachedCacheConfig memcachedCacheConfig = new MemcachedCacheConfig(); String configHosts = kylinConfig.getMemCachedHosts(); memcachedCacheConfig.setTimeout(kylinConfig.getQuerySegmentCacheTimeout()); // set max object size a little less than 1024 * 1024, because the key of the segment result cache is long // if set to 1024 * 1024 will cause memcached client exceed max size error memcachedCacheConfig.setMaxObjectSize(1040000); memcachedCacheConfig.setHosts(configHosts); //Reverse the compression setting between Hbase coprocessor and memcached, if Hbase result is compressed, memcached will not compress. memcachedCacheConfig.setEnableCompression(!kylinConfig.getCompressionResult()); String cacheName = SEG_QUERY_CACHE_NAME; memcachedCache = new MemcachedChunkingCache(MemcachedCache.create(memcachedCacheConfig, cacheName)); }
private SegmentQueryCache() {
KylinConfig kylinConfig = KylinConfig.getInstanceFromEnv();
MemcachedCacheConfig memcachedCacheConfig = new MemcachedCacheConfig();
String configHosts = kylinConfig.getMemCachedHosts();
memcachedCacheConfig.setTimeout(kylinConfig.getQuerySegmentCacheTimeout());
// set max object size a little less than 1024 * 1024, because the key of the segment result cache is long
// if set to 1024 * 1024 will cause memcached client exceed max size error
memcachedCacheConfig.setMaxObjectSize(1040000);
memcachedCacheConfig.setHosts(configHosts);
//Reverse the compression setting between Hbase coprocessor and memcached, if Hbase result is compressed, memcached will not compress.
memcachedCacheConfig.setEnableCompression(!kylinConfig.getCompressionResult());
String cacheName = SEG_QUERY_CACHE_NAME;
memcachedCache = new MemcachedChunkingCache(MemcachedCache.create(memcachedCacheConfig, cacheName));
}
看来 Kylin 在操作 Memcached 时已经意识到大并发写入 1 MB 的数据可能会出现问题,所以将 maxObjectSize 置为了 1040000,并不接近 1048576。
最终只能靠实验来测试到底什么样的数据量可能触发这个问题
import net.spy.memcached.BinaryConnectionFactory;import net.spy.memcached.MemcachedClient;import net.spy.memcached.transcoders.SerializingTranscoder;import java.io.IOException;import java.net.InetSocketAddress;import java.util.ArrayList;import java.util.List;public class Main2 { public static void main(String[] args) throws IOException { List<InetSocketAddress> addrs = new ArrayList<>(); addrs.add(new InetSocketAddress("******", 12000)); MemcachedClient client = new MemcachedClient(new BinaryConnectionFactory(), addrs); SerializingTranscoder transcoder = new SerializingTranscoder(); transcoder.setCompressionThreshold(Integer.MAX_VALUE); byte[] data = new byte[1048000]; while (true) { String keyS = "test"; client.set(keyS, 60, data, transcoder); } }}
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.transcoders.SerializingTranscoder;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
public class Main2 {
public static void main(String[] args) throws IOException {
List<InetSocketAddress> addrs = new ArrayList<>();
addrs.add(new InetSocketAddress("******", 12000));
MemcachedClient client = new MemcachedClient(new BinaryConnectionFactory(), addrs);
SerializingTranscoder transcoder = new SerializingTranscoder();
transcoder.setCompressionThreshold(Integer.MAX_VALUE);
byte[] data = new byte[1048000];
while (true) {
String keyS = "test";
client.set(keyS, 60, data, transcoder);
通过上述代码疯狂写入 Memcached,并未出现空指针异常。
但是该例子并不能代表 Kylin 实际向 Memcached 中写入的最大的数据量,因为 Kylin 是通过自己包装的 MemcachedChunkingCache 进行写入操作。
下面只需要算一算什么样的 byte[] 能触发 Kylin 写入极限大小的数据量了。
观察下面这部分代码:
public static int getValueSplit(MemcachedCacheConfig config, String keyS, int valueBLen) { // the number 6 means the chunk number size never exceeds 6 bytes final int valueSize = config.getMaxObjectSize() - Shorts.BYTES - Ints.BYTES - keyS.getBytes(Charsets.UTF_8).length - 6; final int maxValueSize = config.getMaxChunkSize() * valueSize; Preconditions.checkArgument(valueBLen <= maxValueSize, "the value bytes length [%d] exceeds maximum value size [%d]", valueBLen, maxValueSize); return (valueBLen - 1) / valueSize + 1; }
public static int getValueSplit(MemcachedCacheConfig config, String keyS, int valueBLen) {
// the number 6 means the chunk number size never exceeds 6 bytes
final int valueSize = config.getMaxObjectSize() - Shorts.BYTES - Ints.BYTES
- keyS.getBytes(Charsets.UTF_8).length - 6;
final int maxValueSize = config.getMaxChunkSize() * valueSize;
Preconditions.checkArgument(valueBLen <= maxValueSize,
"the value bytes length [%d] exceeds maximum value size [%d]", valueBLen, maxValueSize);
return (valueBLen - 1) / valueSize + 1;
只要让 valueBLen 是 valueSize 的整数倍即可。我们来个 50 倍试试看。
valueSize 算出是 1047230,再算上序列化操作后的一些字节变化,最后我们只需要保证数据量为 52361473 即可。
测试代码改成如下样子:
import cn.dxy.ops.chaos.cache.memcached.MemcachedCache;import cn.dxy.ops.chaos.cache.memcached.MemcachedCacheConfig;import cn.dxy.ops.chaos.cache.memcached.MemcachedChunkingCache;public class Main3 { public static void main(String[] args) { MemcachedCacheConfig memcachedCacheConfig = new MemcachedCacheConfig(); memcachedCacheConfig.setHosts("t1:12000"); memcachedCacheConfig.setEnableCompression(false); memcachedCacheConfig.setTimeout(2000); MemcachedCache memcachedCache = new MemcachedChunkingCache(MemcachedCache.create(memcachedCacheConfig, "query_segment_cache")); byte[] data = new byte[52361473]; while (true) { String keyS = "test_agg_group_294958b3-1829-cd88-6d01-f44ed1d22067_.org.apache.kylin.cube.gridtable.CubeCodeSystem\\x00\\x04\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x01x\\x09Cuboid 15\\x06\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x06bigint\\xFF\\xFF\\x06bigint\\xFF\\xFF\\x00\\x01\\x0F\\x02\\x01\\x0F\\x010\\x00\\x00\\x01\\x0F\\x00\\x01\\x0F\\x00\\x00\\x00\\x08NO_LIMIT\\x8C\\x7F\\xFF\\xFF\\xFF\\x8C\\x7F\\xFF\\xFF\\xFF\\x19SCAN_FILTER_AGGR_CHECKMEM\\x01\\x01"; memcachedCache.put(keyS, data); } }}
import cn.dxy.ops.chaos.cache.memcached.MemcachedCache;
import cn.dxy.ops.chaos.cache.memcached.MemcachedCacheConfig;
import cn.dxy.ops.chaos.cache.memcached.MemcachedChunkingCache;
public class Main3 {
public static void main(String[] args) {
memcachedCacheConfig.setHosts("t1:12000");
memcachedCacheConfig.setEnableCompression(false);
memcachedCacheConfig.setTimeout(2000);
MemcachedCache memcachedCache = new MemcachedChunkingCache(MemcachedCache.create(memcachedCacheConfig, "query_segment_cache"));
byte[] data = new byte[52361473];
String keyS = "test_agg_group_294958b3-1829-cd88-6d01-f44ed1d22067_.org.apache.kylin.cube.gridtable.CubeCodeSystem\\x00\\x04\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x03x\\x00\\x8F\\x82\\xAC\\xED\\x00\\x05sr\\x00-org.apache.kylin.cube.gridtable.TrimmedDimEnc\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xr\\x00,org.apache.kylin.dimension.DimensionEncoding\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x0C\\x00\\x00xpw\\x02\\x00\\x01x\\x09Cuboid 15\\x06\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x07integer\\xFF\\xFF\\x06bigint\\xFF\\xFF\\x06bigint\\xFF\\xFF\\x00\\x01\\x0F\\x02\\x01\\x0F\\x010\\x00\\x00\\x01\\x0F\\x00\\x01\\x0F\\x00\\x00\\x00\\x08NO_LIMIT\\x8C\\x7F\\xFF\\xFF\\xFF\\x8C\\x7F\\xFF\\xFF\\xFF\\x19SCAN_FILTER_AGGR_CHECKMEM\\x01\\x01";
memcachedCache.put(keyS, data);
执行上面的代码基本基本每次都可以触发空指针异常,有概率触发 Memcached IO 线程死亡。
Exception in thread "Memcached IO over {MemcachedConnection to ******}" java.lang.NullPointerException at net.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer (TCPMemcachedNodeImpl.java:206) at net.spy.memcached.MemcachedConnection.handleWrites (MemcachedConnection.java:811) at net.spy.memcached.MemcachedConnection.handleInputQueue (MemcachedConnection.java:596) at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:423) at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:1457)
at net.spy.memcached.protocol.TCPMemcachedNodeImpl.fillWriteBuffer (TCPMemcachedNodeImpl.java:206)
at net.spy.memcached.MemcachedConnection.handleWrites (MemcachedConnection.java:811)
at net.spy.memcached.MemcachedConnection.handleInputQueue (MemcachedConnection.java:596)
此时,在对数据进行 UTF-8 编码之后,实际并发写入的数据量为 1048571 byte。
我们将 Main2 中的数据量从 1048000 改为 1048571 然后再次执行,会发现也有概率触发 Exception in thread "Memcached IO over {MemcachedConnection to ******" java.lang.NullPointerException 的问题了。
结论
越是诡异的问题,改动起来可能越小,这么看来,直接将 maxObjectSize 从 1040000 改为 1000000 可能更保险一些。
相关 Issue:KYLIN-4074
本文作者简介
周天鹏,丁香园大数据运维工程师,Apache Kylin Committer,“2019 最佳 Apache Kylin 社区贡献个人奖”获得者,主要负责 OLAP 平台的开发与维护。
作者简书账号:
https://www.jianshu.com/u/76a9b45adedb
近年来,随着商业环境的竞争日益激烈,企业对于实时数据服务的需求急剧增加。Kyligence 在服务众多客户的过
数据要素在银行各业务领域和流程中发挥着至关重要的作用,面对激烈的市场竞争和客户需求,银行越来越注重从数据管理中
作为一名消费者,炎热的夏天我们会走进一家便利店,从冰柜中选出一瓶汽水;下午工作有点累了,我们会在公司的自动贩卖
2024 年伊始,Kyligence 联合创始人兼 CEO 韩卿(Luke)分享了对 AI 与数据行业的一些战
房地产行业是我国国民经济中的重要支柱产业之一,在房地产市场供求关系发生重大变化的当下,房企面临多重挑战。Kyl
今年年初,Kyligence 高级副总裁兼合伙人葛双寅(Silas Ge)受邀在阿斯利康“跃行致远三十周年年会
2024 年伊始,Kyligence 联合创始人兼 CEO 韩卿在公司内部的飞书订阅号发表了多篇 Rethin
400 8658 757
工作日:10:00 - 18:00
已有账号? 点此登陆
预约演示,您将获得
完整的产品体验
从数据导入、建模到分析的全流程操作演示。
行业专家解惑
与资深行业专家的交流机会,解答您的个性化问题。
请填写真实信息,我们会在 1-2 个工作日内电话与您联系。
全行业落地场景演示
涵盖金融、零售、餐饮、医药、制造等多个行业,最贴合您的业务需求与场景。
Data + AI 应用落地咨询
与资深技术专家深入交流,助您的企业快速落地 AI 场景应用。
立即预约,您将获得
精准数据计算能力:
接入高精度数值计算大模型服务,为您的企业级AI应用提供强大支持。
个性化业务场景解决方案:
量身定制的计算模型和数据分析服务,切实贴合您的业务需求和应用场景。
Data + AI 落地应用咨询:
与资深专家深入探讨数据和 AI 如何帮助您的企业加速实现应用落地,构建更智能的数据驱动未来。
申请体验,您将获得
体验数据处理性能 2x 加速
同等规模资源、同等量级数据、同一套数据处理逻辑,处理耗时下降一半
专家支持
试用部署、生成数据、性能对比各操作环节在线支持