Giter Site home page Giter Site logo

mycatapache / mycat2 Goto Github PK

View Code? Open in Web Editor NEW
1.6K 91.0 468.0 19.87 MB

MySQL Proxy using Java NIO based on Sharding SQL,Calcite ,simple and fast

Home Page: http://www.mycat.org.cn/

License: GNU General Public License v3.0

Java 99.38% Batchfile 0.02% Shell 0.01% Dockerfile 0.02% HTML 0.56%
mycat mysql proxy calcite nio vertx sharding sql mariadb async

mycat2's Introduction

Mycat2

Distributed database based on MySQL or JDBC.

官网

http://mycatone.top/

Software introduction

Mycat2 is a distributed relational database (middleware) developed by the Mycat community. It supports distributed SQL queries, is compatible with the MySQL communication protocol, supports a variety of back-end databases with Java ecology, and improves data query processing capabilities through data fragmentation.

软件介绍

Mycat2是Mycat社区开发的一款分布式关系型数据库(中间件)。它支持分布式SQL查询,兼容MySQL通信协议,以Java生态支持多种后端数据库,通过数据分片提高数据查询处理能力。

gitee:https://gitee.com/MycatOne/Mycat2

github:https://github.com/MyCATApache/Mycat2

v1.22-release

doc-en doc-cn

Stargazers over time

Features

  1. Open source code Learning middleware technology, database technology, and code is a must.
  2. Distributed query engine compatible with MySQL syntax • Compatible with MySQL syntax. • Compatible with MySQL value types. • Use an optimizer based on rule optimization and cost. • Independent physical execution engine.
  3. Custom function algorithm development • Sharding algorithm, serial number algorithm, load balancing algorithm, etc. can all be customized to load. • The query engine can run away from the network framework.
  4. Customize the process Self-developed DSL manipulates the physical query plan. Support SQL forwarding and cache result set.

Framework

Currently, only mycat2 is supported on java8, and will be supported in other versions later.

License

Apache LICENSE from 2023.8

mycat2's People

Contributors

celebrate-future avatar dependabot[bot] avatar ezkayotwjprkxwcuyeeb avatar flylkng avatar junwen12221 avatar jy2156121 avatar lonwolonwo avatar mycat2022 avatar wangzihaogithub avatar yinhaibo avatar zwyqz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mycat2's Issues

【设计分享】MycatActorThread的多线程问题

Reactor的资源是私有的,为了避免多线程问题,提供了异步任务队列,ReactorThread循环处理的间隙会查看有没有要处理的任务,这样就解决问题,需要注意,这些任务必须是非阻塞,很短时间内完成的,并且任务里面最后不要有日志输出这样的语句,更不能IO事件,如果有IO数据,则传到Job里
下面是一个参考用法代码:
public void clearAndDestroyCons(String reason) {
logger.info("clear and destroy connections of {} ,for reason ", this, reason);
ProxyRuntime runtime = ProxyRuntime.INSTANCE;
final MySQLMetaBean target = this;
MycatReactorThread[] reactorThreads = (MycatReactorThread[]) runtime.getReactorThreads();
// 每个MycatReactorThread异步清理自己使用的连接池
for (MycatReactorThread f : reactorThreads) {
f.addNIOJob(() -> {
f.clearAndDestroyMySQLSession(target, reason);
});
}
}

SQL异步执行框架

多个SQL过来执行的时候,第一个执行结束了,继续触发第二执行,包括确定什么情况下合并透传,以及是否结果集判断和连接释放的逻辑正确,究竟是否单表模式下,不存在分隔多个SQL独立顺序执行的情况,也思考下, 但多库,不同表在不同库的最简单路由情况,的确存在多个SQL路由到不同节点顺序执行的问题

任务负责:国哥

【设计讨论】Mycat内存管理篇

内存池的问题在2.0模式下需要修正,目前的设计思路:
每个Reactor线程一个(简单)内存池,用于前后端连接的固定大小的内存分配,不存在同步与并发锁的问题。
一个所有线程共享的复杂内存池,用于大内存的分配,如SQL结果集的缓存等功能,此内存池需要考虑高并发问题,堆外内存与文件映射内存共处,内存失效标记,比如人工或定时清理释放了某些内存,导致这些内存失效,当缓存模块尝试加载时,发现内存无效,于是重新加载,即内存池可以分配几种内存:可交换到文件存储的内存、可以手工清理释放的内存、不能清理的内存等。

【设计讨论】Mycat的状态问题

连接有关的状态(前端连接,后端连接等),分为两种,一种是当前执行的SQL的相关状态,一种是整个Session会话期内的状态,后者可以设计为Session的属性,防止Session会话期状态膨胀。

咨询oracle分布式查询场景

咨询oracle分布式查询场景
比如我有3个oracle数据库实例,每个数据库都有1个相同的表,但这3个表中的数据都不重复,前端在查询的时候需要自动做3个表的合并,mycat适用这个场景吗?

【征集方案】Mycat 2.0核心执行异步设计框架

一个高消耗的SQL 限流每分钟10次,这种限流又不能类似普通限流做法,直接返回EROR,而是要等待上上一个SQL结束后再继续。谁能给出优雅通用的异步设计框架?此框架有很多用途:
一个SQL的结果集来自某个本地文件,而此文件又是用户自己的程序输出的,当文件写完后,SQL引擎读取文件并返回结果集。

schema配置与命令设计方案 v1.0

方案一:

1 DataHost:
1) 创建DataHost:create DataHost mysql_1(dataSource, address, user, password, minCon, maxCon, maxRetryCount) values (source_1, 192.168.1.11:3306, root, 123456, 10, 100, 3);
2) 删除DataHost:delete DataHost mysql_1;
3) 修改DataHost:update DataHost set password = 654321 where DataHostName = mysql_1;
4) 查询DataHost:select * from DataHost;

2 DataSource:
1) 创建DataSource:create DataSource source_1(repType, switchType, balanceType) values (MASTER_SLAVE, SWITCH, BALANCE_ALL_READ);
2) 删除DataSource:delete DataSource source_1;
3) 修改DataSource:update DataSource set password = 654321 where DataSourceName = source_1;
4) 查询DaraSource:select * from DataSource;

3 DataNode:
1) 创建DataNode:create DataNode dn1(DataSource, DataBases) values(source_1, db1); /**/
2) 删除DataNode:delete DataNode dn1 where DataSource = source_1;
3) 修改DataNode:update DataNode set DataBases = db2 where DataSource = source_1 and DataNode = dn1;
4) 查询DataNode:select * from DataNode;

4 DataBase(schema):
格式同上

方案二:

1 DataHost:
1) 创建DataHost:@@config DataHost dataSource = source_1, name = mysql_1, address = 192.168.1.11:3306, user = root, password = 123456, minCon = 10, maxCon = 100, maxRetryCount = 3;
2) 删除DataHost:@@delete DataHost name = mysql_1;
3) 修改DataHost:@@modify DataHost dataSource = source_1, name = mysql_1, password = 654321, minCon = 20;
4) 查询DataHost:
@@show DataHosts;
@@show DataHosts dataSource = source_1;
@@show DataHosts dataSource = source_1, name = mysql_1;

2 DataSource:
1) 创建DataSource:@@config DataSource name = source_1, repType = MASTER_SLAVE, switchType = SWITCH, balanceType = BALANCE_ALL_READ;
2) 删除DataSource:@@delete DataSource name = source_1;
3) 修改DataSource:@@modify DataSource name = source_1, switchType = NOSWITCH;
4) 查询DaraSource:
@@show DataSources;
@@show DataSources dataSource = source_1;
@@show DataHosts dataSource = source_1, name = mysql_1;

3 DataNode:
1) 创建DataNode:@@config DataNode name = dn1, DataSource = source_1, DataBases = db1;
2) 删除DataNode:@@delete DataNode name = dn1;
3) 修改DataNode:@@modify DataNode name = dn1, name = dn2 DataBases = db2;
4) 查询DataNode:
@@show DataNodes;
@@show DataNodes DataSource = source_1;
@@show DataNode name = dn1;

4 DataBase(schema):
格式同上

方案三:

1 效仿阿里云DRDS,Mycat定位为分布式数据库中间件,不负责实体库的主从切换、读写分离的sql路由(这两项划为云数据库功能范畴,后面再说云数据库的概念)。只有提供DataHost、DataBase和Table的定制。
2 Mycat每配置一个DataHost时指定每个DataHost上的database个数,并自动在DataHost上创建database;Mycat在DataHost上创建database时记录每个database的属性。
3 Mycat创建DataBase时指定使用哪些database;
4 Mycat创建Table时可指定分库键或指定分库键和分表键;也可不指定分库分表键;此时认为表为全局表;
5 云数据库(CRDS):利用mysql的binlog配置主从复制和开源的keepalive实现多副本单实例(暴露的虚拟mysql IP和Prot对应后端的多mysql IP和Prot)

集群异常

前提: 一、1、2、3集群配置文件正确
二、win10系统。
三、mysql本地一个实例。
四、mycat实例3个在一台机器,不同的端口。
**现象:**1、2、3起来后,1、2、3可以联通
2关闭,再起来2。集群1、2、3都可以联通
1关闭,再起来1,集群内,1无法联通。2、3正常
1的错误信息是:
INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.man.DefaultAdminSessionManager createSession at 44]-[INFO] connected to cluster port .java.nio.channels.SocketChannel[connected local=/127.0.0.1:57772 remote=/127.0.0.1:9067]create session io.mycat.proxy.man.AdminSession@129138e INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.man.DefaultAdminSessionHandler onConnect at 71]-[INFO] socket connect success INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.AbstractSession readSocket at 169]-[DEBUG] readed 43 total bytes INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.util.StringUtil dumpAsHex at 128]-[DEBUG] offset = 0, length = 43, end = 43, n = 3 INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.AbstractSession receivedPacket at 138]-[INFO] session 2 packet: offset = 0, length = 43, type = 2, cur total length = 43,pkg HEX INFO | jvm 1 | 2017/09/25 23:07:00 | 28 00 02 6c 65 61 64 65 ( . . l e a d e INFO | jvm 1 | 2017/09/25 23:07:00 | 72 2d 33 00 02 f0 8c 91 r - 3 . . . . . INFO | jvm 1 | 2017/09/25 23:07:00 | b9 5e 01 00 00 6c 65 61 . ^ . . . l e a INFO | jvm 1 | 2017/09/25 23:07:00 | 64 65 72 2d 31 00 84 1f d e r - 1 . . . INFO | jvm 1 | 2017/09/25 23:07:00 | 00 00 5d 89 91 b9 5e 01 . . ] . . . ^ . INFO | jvm 1 | 2017/09/25 23:07:00 | 00 00 00 . . . INFO | jvm 1 | 2017/09/25 23:07:00 | INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.man.MyCluster onClusterNodeUp at 116]-[INFO] Node online leader-3 at 127.0.0.1:9068 started at 2017-09-25 23:04:36.445 cluster leader leader-1 cluster state Clustered cluster time:1506351877360 proxy port:8068 INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.man.MyCluster onClusterNodeUp at 124]-[INFO] send join cluster message to leader leader-3 INFO | jvm 1 | 2017/09/25 23:07:00 | 23:07:00 T=NIO-Acceptor [io.mycat.proxy.ProxyReactorThread run at 144]-[WARN] Socket IO err : INFO | jvm 1 | 2017/09/25 23:07:00 | java.lang.NullPointerException INFO | jvm 1 | 2017/09/25 23:07:00 | at io.mycat.proxy.man.MyCluster.onClusterNodeUp(MyCluster.java:127)

超过buffer限制的sql,mycat2.0报错

背景:sql解析器的hashArray组件使用了固定长度的数组保存分词信息,但是没有实现动态扩容机制
1.阅读HashArray.java和BufferSQLContext.java文件里面的注释
2.提出解决方案并与SQLParser作者确认
3.提交解决问题的代码

MyCAT 2.0 路由结果以及路由工具设计

背景:路由结果是多节点数据源处理的依据,参考1.6的代码和工具类实现
1.可以保存SQL语法解析结果,分库分表多种情况以及提供合拼SQL结果集的必要参数
2.路由结果亦可是流式编程的中间物,路由结果可以表达流式编程的多数据源操作
3.高性能

mycat2什么时候可用?

大致看了下,现在好像还没有sharding功能?
什么时候可用?
或者有没有明确的sharding思路,可以大家一起来加代码。

【志愿者任务】Fake MySQL Server

难度指数 3颗星

Mycat需要一个Fake MySQL Server,这个Server可以直接阻塞IO方式来写,要求是应答报文可以文本方式配置,java类自定义产生的报文,有类似配置文件 xxxx rsult.txt> 或者mysult.class,用来生成任意的结果集匹配。
任务需要先给出框架性设计,含主要接口,设计思路,配置文件,然后具体协作开发,
有意者可以追贴认领,任何设计思路都欢迎追贴建议。

XA:使用atomikos进行分布式事务一直集成不成功

2018-12-21 11:17:53,046 INFO o.a.c.c.C.[.[.[/] [] - [Initializing Spring FrameworkServlet 'dispatcherServlet']
2018-12-21 11:17:53,046 INFO o.s.w.s.DispatcherServlet [] - [FrameworkServlet 'dispatcherServlet': initialization started]
2018-12-21 11:17:53,082 INFO o.s.w.s.DispatcherServlet [] - [FrameworkServlet 'dispatcherServlet': initialization completed in 36 ms]
2018-12-21 11:17:53,155 DEBUG c.a.i.i.CompositeTransactionManagerImp [] - [createCompositeTransaction ( 5000 ): created new ROOT transaction with id 127.0.0.1.tm154536227313100001]
2018-12-21 11:17:53,210 DEBUG c.a.j.AbstractDataSourceBean [] - [AtomikosDataSoureBean 'one': getConnection()...]
2018-12-21 11:17:53,210 INFO c.a.j.AbstractDataSourceBean [] - [AtomikosDataSoureBean 'one': init...]
2018-12-21 11:17:53,210 WARN c.a.j.AbstractDataSourceBean [] - [AtomikosDataSoureBean 'one': poolSize equals default - this may cause performance problems!]
2018-12-21 11:17:53,211 INFO c.a.j.AtomikosDataSourceBean [] - [AtomikosDataSoureBean 'one': initializing with [ xaDataSourceClassName=com.alibaba.druid.pool.xa.DruidXADataSource, uniqueResourceName=one, maxPoolSize=1, minPoolSize=1, borrowConnectionTimeout=30, maxIdleTime=60, reapTimeout=0, maintenanceInterval=60, testQuery=null, xaProperties=[validationQuery=SELECT 'ZTM' FROM DUAL,url=jdbc:mysql://10.100.24.6:8066/bizcenter?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false,password=123456,driverClassName=,filters=stat,wall,slf4j,username=Mbizcenter], loginTimeout=0, maxLifetime=0]]
2018-12-21 11:17:54,359 INFO c.a.d.p.DruidDataSource [] - [{dataSource-1} inited]
2018-12-21 11:17:54,378 INFO c.a.d.x.XATransactionalResource [] - [one: refreshed XAResource]
2018-12-21 11:17:54,393 WARN c.a.r.x.XaResourceRecoveryManager [] - [Error while retrieving xids from resource - will retry later...]
com.mysql.jdbc.jdbc2.optional.MysqlXAException: Undetermined error occurred in the underlying Connection - check your data for consistency
at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.mapXAExceptionFromSQLException(MysqlXAConnection.java:586)
at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.recover(MysqlXAConnection.java:316)
at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.recover(MysqlXAConnection.java:244)
at com.atomikos.datasource.xa.RecoveryScan.recoverXids(RecoveryScan.java:32)
at com.atomikos.recovery.xa.XaResourceRecoveryManager.retrievePreparedXidsFromXaResource(XaResourceRecoveryManager.java:158)
at com.atomikos.recovery.xa.XaResourceRecoveryManager.recover(XaResourceRecoveryManager.java:67)
at com.atomikos.datasource.xa.XATransactionalResource.recover(XATransactionalResource.java:449)
at com.atomikos.datasource.xa.XATransactionalResource.setRecoveryService(XATransactionalResource.java:416)
at com.atomikos.icatch.config.Configuration.addResource(Configuration.java:249)
at com.atomikos.jdbc.AtomikosDataSourceBean.doInit(AtomikosDataSourceBean.java:183)
at com.atomikos.jdbc.AbstractDataSourceBean.init(AbstractDataSourceBean.java:292)
at com.atomikos.jdbc.AbstractDataSourceBean.getConnection(AbstractDataSourceBean.java:343)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:338)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:84)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
at com.sun.proxy.$Proxy94.update(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
at com.sun.proxy.$Proxy94.update(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
at com.sun.proxy.$Proxy74.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy76.save(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy77.save(Unknown Source)
at com.power.learn.service.impl.StudentOneServiceImpl.save(StudentOneServiceImpl.java:39)
at com.power.learn.service.impl.StudentOneServiceImpl$$FastClassBySpringCGLIB$$fa9c375.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.power.learn.service.impl.StudentOneServiceImpl$$EnhancerBySpringCGLIB$$1785f7ee.save()
at com.power.learn.service.impl.StudentOneServiceImpl$$FastClassBySpringCGLIB$$fa9c375.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.power.learn.service.impl.StudentOneServiceImpl$$EnhancerBySpringCGLIB$$7bafb915.save()
at com.power.controller.StudentOneController.save(StudentOneController.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: com.alibaba.druid.sql.parser.ParserException: syntax error, error in :'XA RECOVER',expect IDENTIFIER, actual IDENTIFIER XA
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2480)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2438)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1381)
at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.recover(MysqlXAConnection.java:295)
... 145 common frames omitted

使用mysql原生没问题。请问,mycat是否对支持XA还是有问题,如何解决。

基于静态注解实现分库分表功能

前提: Mycat 2.0先能实现1.6的全功能,再考虑优化

  1. 研究Mycat1.6代码如何合并排序多节点数据的,并编写Mycat 2.0实现SQL结果集合拼的设计文档
  2. 验证SQL结果集合拼
  3. sql解析不需要,注解确定路由,合并,排序,分页的信息
  4. 完成分库功能
  5. 完成分表功能

ProxyBuffer问题

背景:
1.mycat.yml中的bufferPoolChunkSize过小,比如64,导致构造AuthPackge空间不足报错
具体出错位置为MycatSession.sendAuthPackge,解决办法为根据内存大小动态调整 设置的值
2.当bufferPoolChunkSize小于90时,BackendIOTaskWithResultSet的onSocketRead在连接后端mysql时候不能处理ProxyBuffer中的数据,导致不断输出readed zero bytes ,Maybe a bug ,please fix it !!!!

管理命令

增加管理命令,mycat fetch config,返回三列?的表格,文件名称,修改时间,内容(文本),为了Web管理界面调用,展现配置文件内容

以及对应的 mycat update config xxx.conf <文件内容> ,即上传和更新生效某个配置文件,返回一行的Table,optcode ?错误码,以及说明。。。

包括返回集群状态的表格,哪几个节点,谁是Leader。以及是否有Proxy,Proxy的状态,节点上下线,这些都以后要命令行实现,同时给Web使用

所有管理命令都可以被Web调用

【待定任务】拦截任意SQL并返回合适的结果

Mycat2看来拦截特定SQL, 并返回“正确”的伪数据包,也很重要了,
,比如sleep(xxx),比如一个有安全问题的SQL,一个非常慢的SQL等,返回合适的结果,比OK,ERROR,孔结果集,指定内容的结果集等。
设计思路可以跟帖

读写分离的负载均衡问题,前面3000个查询请求可以平均分配到各个readhost,后面再多的读请求都是分配到一个固定的readhost,其他readhost都不接受读的请求。

读只走第writehost[163.1.9.246:3307]下的第一个readhost[163.1.9.244:3307]和备用writehost[163.1.9.249:3308],为啥不走第二个readhost[163.1.9.249:3307]呢?
而且当第一个readhost[163.1.9.244:3307]手动kill之后,查询也不会启用第二个readhost[163.1.9.249:3307],只走备用writehost[163.1.9.249:3308],这个现象是啥原因,是我配的不对还是不科学呢?求大神指教,谢谢。
schema.xml配置文件如下。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="fsrp" checkSQLschema="false" sqlMaxLimit="100" dataNode="d1"></schema>
        <dataNode name="d1" dataHost="S249" database="fsrp" />
        <dataHost name="S249" maxCon="2000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="1
00">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="163.1.9.246:3307" user="root" password="root">
                        <readHost host="hostS2" url="163.1.9.244:3307" user="root" password="root" />           
                        <readHost host="hostS1" url="163.1.9.249:3307" user="root" password="root" />
                </writeHost>
                <writeHost host="hostM2" url="163.1.9.249:3308" user="root" password="root" />
        </dataHost>
</mycat:schema>

【设计讨论】Mycat2心跳检查的设计

如果当前DataHost没有任何连接,心跳是可以创建一个连接去检查的,这种情况对应主从切换后,某个数据源连接池关闭,没有连接
如果有连接,怎么处理?这个逻辑可能比较复杂,谁有兴趣,可以先整理逻辑,然后去改造
还有一个地方,最好是多个Reactor线程一起完成所有DataHost心跳的检测,而不是每个都完成所有的,然后有失败的,则通知其他Reactor线程?

使用一条查询语句压测,出现停止工作情况,再无日志输出

23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
Recieved SQL : SELECT * FROM db2.travelrecord;
23:20:52 T=NIO_Thread 2 [io.mycat.mycat2.beans.MySQLRepBean getBalanceMetaBean at 249]-[WARN] all slaveNode is Unavailable. use master node for read . balance type is BALANCE_ALL_READ
23:21:32 T=NIO_Thread 3 [io.mycat.mycat2.tasks.BackendConCreateTask at 45]-[INFO] Connecting to backend MySQL Server 127.0.0.1:3306

mycat2.0论题交流及结论 2018-10-20

1.Mycat 2.0 支持全局表,分库键,分库键+分表键。
2.Mycat 2.0 创建逻辑库时使用已有的所有物理数库(所有datahost内的database)。
3.Mycat 2.0 扩容datahost时指定该datahost内database的个数,database的创建由mycat自动完成,并记录每个database的信息。
4.Mycat配置命令使用《schema配置与命令设计方案.txt》中的“方案一”所列的格式。
5.Mycat建表语句支持分库表、分库分表的创建。在建表语句中添加 “dbpartition 字段名”或“tbpartition 字段名”即可。
6.Mycat 2.0 应存储每张表的主键、分片字段、索引字段等信息。

读取本地文件为Mysql ResultSet工具

本地文件要求:
1.常用数据库管理工具导出文件格式,如CSV,具备友好的编辑性质优先支持
2.要求有字段及其类型等信息以生成字段信息
3文件内可能需要有数据库信息,基字符集,排序规则,表名

运行时要求:
1.实现函数获取字段包
2.实现迭代器返回ResultSet包对象
3.处理过程中不能出现内存使用量明显增长
4.尽量不使用字符串,尽量结果集内容在堆外(若使用堆外ByteBuffer,需有内存池接口).
5..字段包、结果集包与mysql协议一致
6.性能因素(堆内堆外,缓冲区...)

problem

小建议:

1 mycat2.0的配置文件是不是太多了,这样可能用户使用起来配置相对麻烦.学习成本相对较高

2 然后建议可以增加一些文档,比如设计流程,roadmap,issues规范等等

3 可能一些脚本,快速搭建测试环境之类的.

这样可能优化新用户的使用和减少成为commitor的学习成本.有益于对整个mycat2.0的社区发展.

实现逻辑库,逻辑表。

首先DBINMultiServerCmdStrategy里面的initMySqlCmdHandler,
方法添加一行MYSQLCOMMANDMAP.put(BufferSQLContext.SHOW_SQL, SqlComStartCmd.INSTANCE);语句,修改SqlComStartCmd中的procssSQL方法,加一个判断,
如果当前的sql语句为SHOW DATABASES,则
return new MycatShowDatabases().procssSQL(session);
如果当前语句为SHOW FULL TABLES WHERE Table_type != 'VIEW' , 则
return new MycatShowTables().procssSQL(session);
另外在MycatConfig中添加mycatSchemaMap的set/get方法。
最后就是实现MycatShowDatabases和MycatShowTables这两个类,根据配置文件中的信息向客户端发送mysql协议。

SQL结果集缓存工具

1.尽可能满足的要求,如果确认存在平台缺陷导致功能难以完成,可商讨.
2.使用MappedBuffer完成结果集缓存
a.MapppedBuffer分块管理
b.对变长的SQL结果集的管理可能存在以下方案
一个SQL的结果集仅存在一个
一个文件对应一个结果集缓存(目前实现)
一个文件对应多个结果集缓存
结果集缓存仅存储在内存
3.多线程处理
a.尽量无锁
b.考虑多个客户端在相同的时刻使用相同SQL得到了相同的结果集,怎么做缓存
c.一个线程正在把一个SQL对应的结果集刷盘,有一客户端在相同时刻使用相同SQL获取结果,怎么获取缓存
d.刷盘线程是否需要单独在一个dio线程处理?
4.缓存失效策略以及清理数据
5.针对SQL结果集格式可以实现存储上的优化
上述问题已经在2.0有实现做一定处理,有缺陷
Mycat2\source\src\main\java\io\mycat\mycat2\cmds\cache\mapcache

自定义结果集

一个文本文件,对应某个SQL的结果集,采用(动态或静态)注解方式来指定特定SQL读取特定结果集文件(结果集文件是URL方式指定,可以是http://xxx ,共享目录中文件),结果集文件可以在第一行表示类型,比如仅仅是OK,ERRO,或者 ResultSet,需要仍然无阻塞方式去读取文件,前端写完后,异步触发第二次读写,直到结果集完成

Mycat 2.0 HBT技术解决 多表关联案例 设计 完善

Mycat 2.0 HBT技术解决 多表关联案例
HBT的终极路线,类似Spark SQL这样的,但不去尝试自动实现SQL结果,而是人工去确定每一步所用的函数和过程,人脑职能。
对于HBT程序来说,Mycat 2.0 HBT技术解决多表关联案例 .
select a.id,a.price,b.username where a.id in (111,222,333,444) and b.id=a.id ,
这个SQL就对应一个HBT代码,所以这个SQL的模式是固定的,不固定仅仅是里面的查询条件,翻页。
HBT可能需要动态注解的匹配功能以及提取信息功能的支持,此提取的信息是HBT的参数,具体是某个字段,数字,字符串甚至一个查询条件等等。用户编写HBT代码到action并编译成class文件,动态注解加载class文件.数据库客户端请求到来,动态注解根据sql匹配action,HBT代码可以控制mysql session对数据库进行操作,并操纵数据库返回的数据,最后把结果返回到数据库客户端.HBT代码是类似Spark SQL风格的.

注重用户体验,容易debug,先出设计文档,再实现功能,再考虑优化

mycat 功能验证

mycat 功能验证
mycat tpcc 测试
mycat 客户端兼容测试
可能涉及到主流的连接池

SQL解析过程出现下标为负数

java.lang.NegativeArraySizeException
at io.mycat.mycat2.sqlparser.byteArrayInterface.ByteArrayInterface.getString(ByteArrayInterface.java:20)
at io.mycat.mycat2.sqlparser.BufferSQLContext.getRealSQL(BufferSQLContext.java:353)
at io.mycat.mycat2.cmds.strategy.AbstractCmdStrategy.matchMySqlCommand(AbstractCmdStrategy.java:118)
at io.mycat.mycat2.MycatSession.matchMySqlCommand(MycatSession.java:95)
at io.mycat.mycat2.net.DefaultMycatSessionHandler.onFrontRead(DefaultMycatSessionHandler.java:90)
at io.mycat.mycat2.net.DefaultMycatSessionHandler.onSocketRead(DefaultMycatSessionHandler.java:34)
at io.mycat.mycat2.net.DefaultMycatSessionHandler.onSocketRead(DefaultMycatSessionHandler.java:28)
at io.mycat.proxy.ProxyReactorThread.processReadKey(ProxyReactorThread.java:99)
at io.mycat.proxy.ProxyReactorThread.run(ProxyReactorThread.java:141)

SQL语法解析增强

1.groupby_clause
2.having_clause
3.group_functions
4.orderby_clause
5.select_list(select_item_list)
4.数据库中间件领域的扁平特定语法

【设计讨论】Mycat NIO与SQL命令的设计问题

目前考虑这样改进,即NIOHandler就只有两个(Auth+Default),透传的逻辑,含LoadData相关的透传的,都融合到DefaultHandler里,MySQLCmd暂时保留,接口后面调整,目前从实现来看,MySQLCmd应该不涉及到后端连接的NIO事件,属于用户自己产生应答报文,如果需要后端操作,也是MySQLCmd这边自己来负责构造其他对象(主要为BackendIOTask)来协助完成

动态创建表设计

需求
某些业务场景会设计到动态表,表动态创建到指定分片,并能添加路由规则。

设计

  1. 建表语句前面添加hint注解,包含注解类型需要建表的分片:
    /*!mycat: type=create,node=[nd1,nd2,nd3],rule=auto-sharding-long */实际建表语句

  2. 解析hint注解,及建表SQL,获取表名称,及分片信息;

  3. 生成新的配置,推送到schem及ZK配置中;

  4. 生成新表的路由规则,添加到系统中;

  5. 根据路由规则,在指定分片执行建表SQL,创建表。

Mycat Exchanger

负责把实现JDBC方式连接Oracle,SQL Server,以及Redis。MongoDB等后端存储的,模拟成标准的MySQL Server,对接Mycat。这样 Mycat就统一支持各种数据库,并且核心还稳定简单。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.